mirror of
https://github.com/github/codeql.git
synced 2026-05-24 08:07:07 +02:00
Compare commits
4 Commits
rc/3.21
...
idrissrio/
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2f793f652e | ||
|
|
8cfa0a3a2d | ||
|
|
d771f1ef0e | ||
|
|
a40719b660 |
4
.bazelrc
4
.bazelrc
@@ -11,8 +11,6 @@ build --compilation_mode opt
|
||||
common --override_module=semmle_code=%workspace%/misc/bazel/semmle_code_stub
|
||||
|
||||
build --repo_env=CC=clang --repo_env=CXX=clang++
|
||||
# Disable Android SDK auto-detection (we don't use it, and rules_android has Bazel 9 compatibility issues)
|
||||
build --repo_env=ANDROID_HOME=
|
||||
|
||||
# print test output, like sembuild does.
|
||||
# Set to `errors` if this is too verbose.
|
||||
@@ -36,7 +34,7 @@ common --@rules_dotnet//dotnet/settings:strict_deps=false
|
||||
common --@rules_rust//rust/toolchain/channel=nightly
|
||||
|
||||
# Reduce this eventually to empty, once we've fixed all our usages of java, and https://github.com/bazel-contrib/rules_go/issues/4193 is fixed
|
||||
common --incompatible_autoload_externally="+@rules_cc,+@rules_java,+@rules_shell"
|
||||
common --incompatible_autoload_externally="+@rules_java,+@rules_shell"
|
||||
|
||||
build --java_language_version=17
|
||||
build --tool_java_language_version=17
|
||||
|
||||
@@ -1 +1 @@
|
||||
9.0.0
|
||||
8.4.2
|
||||
|
||||
67
MODULE.bazel
67
MODULE.bazel
@@ -15,22 +15,20 @@ local_path_override(
|
||||
# see https://registry.bazel.build/ for a list of available packages
|
||||
|
||||
bazel_dep(name = "platforms", version = "1.0.0")
|
||||
bazel_dep(name = "rules_cc", version = "0.2.16")
|
||||
bazel_dep(name = "rules_go", version = "0.59.0")
|
||||
bazel_dep(name = "rules_java", version = "9.0.3")
|
||||
bazel_dep(name = "rules_go", version = "0.56.1")
|
||||
bazel_dep(name = "rules_pkg", version = "1.0.1")
|
||||
bazel_dep(name = "rules_nodejs", version = "6.7.3")
|
||||
bazel_dep(name = "rules_nodejs", version = "6.2.0-codeql.1")
|
||||
bazel_dep(name = "rules_python", version = "0.40.0")
|
||||
bazel_dep(name = "rules_shell", version = "0.5.0")
|
||||
bazel_dep(name = "bazel_skylib", version = "1.8.1")
|
||||
bazel_dep(name = "abseil-cpp", version = "20240116.1", repo_name = "absl")
|
||||
bazel_dep(name = "nlohmann_json", version = "3.11.3", repo_name = "json")
|
||||
bazel_dep(name = "fmt", version = "12.1.0-codeql.1")
|
||||
bazel_dep(name = "rules_kotlin", version = "2.2.2-codeql.1")
|
||||
bazel_dep(name = "gazelle", version = "0.47.0")
|
||||
bazel_dep(name = "rules_kotlin", version = "2.2.0-codeql.1")
|
||||
bazel_dep(name = "gazelle", version = "0.40.0")
|
||||
bazel_dep(name = "rules_dotnet", version = "0.21.5-codeql.1")
|
||||
bazel_dep(name = "googletest", version = "1.14.0.bcr.1")
|
||||
bazel_dep(name = "rules_rust", version = "0.68.1.codeql.1")
|
||||
bazel_dep(name = "rules_rust", version = "0.66.0")
|
||||
bazel_dep(name = "zstd", version = "1.5.5.bcr.1")
|
||||
|
||||
bazel_dep(name = "buildifier_prebuilt", version = "6.4.0", dev_dependency = True)
|
||||
@@ -43,7 +41,7 @@ RUST_EDITION = "2024"
|
||||
# a nightly toolchain is required to enable experimental_use_cc_common_link, which we require internally
|
||||
# we prefer to run the same version as internally, even if experimental_use_cc_common_link is not really
|
||||
# required in this repo
|
||||
RUST_VERSION = "nightly/2026-01-22"
|
||||
RUST_VERSION = "nightly/2025-08-01"
|
||||
|
||||
rust = use_extension("@rules_rust//rust:extensions.bzl", "rust")
|
||||
rust.toolchain(
|
||||
@@ -55,26 +53,26 @@ rust.toolchain(
|
||||
],
|
||||
# generated by buildutils-internal/scripts/fill-rust-sha256s.py (internal repo)
|
||||
sha256s = {
|
||||
"2026-01-22/rustc-nightly-x86_64-unknown-linux-gnu.tar.xz": "88db619323cc1321630d124efa51ed02fabc5e020f08cfa0eda2c0ac1afbe69a",
|
||||
"2026-01-22/rustc-nightly-x86_64-apple-darwin.tar.xz": "08484da3fa38db56f93629aeabdc0ae9ff8ed9704c0792d35259cbc849b3f54c",
|
||||
"2026-01-22/rustc-nightly-aarch64-apple-darwin.tar.xz": "a39c0b21b7058e364ea1bd43144e42e4bf1efade036b2e82455f2afce194ee81",
|
||||
"2026-01-22/rustc-nightly-x86_64-pc-windows-msvc.tar.xz": "d00248ee9850dbb6932b2578e32ff74fc7c429854c1aa071066ca31b65385a3b",
|
||||
"2026-01-22/clippy-nightly-x86_64-unknown-linux-gnu.tar.xz": "70656a0ce994ffff16d5a35a7b170a0acd41e9bb54a589c96ed45bf97b094a4d",
|
||||
"2026-01-22/clippy-nightly-x86_64-apple-darwin.tar.xz": "fe242519fa961522734733009705aec3c2d9a20cc57291f2aa614e5e6262c88f",
|
||||
"2026-01-22/clippy-nightly-aarch64-apple-darwin.tar.xz": "38bb226363ec97c9722edf966cd58774a683e19fd2ff2a6030094445d51e06f9",
|
||||
"2026-01-22/clippy-nightly-x86_64-pc-windows-msvc.tar.xz": "6da9b4470beea67abfebf046f141eee0d2a8db7c7a9e4e2294478734fd477228",
|
||||
"2026-01-22/cargo-nightly-x86_64-unknown-linux-gnu.tar.xz": "99004e9d10c43a01499642f53bb3184d41137a95d65bfb217098840a9e79e892",
|
||||
"2026-01-22/cargo-nightly-x86_64-apple-darwin.tar.xz": "6e021394cf8d8400ac6cfdfcef24e4d74f988e91eb8028b36de3a64ce3502990",
|
||||
"2026-01-22/cargo-nightly-aarch64-apple-darwin.tar.xz": "4b2494cb69ab64132cddbc411a38ea9f1105e54d6f986e43168d54f79510c673",
|
||||
"2026-01-22/cargo-nightly-x86_64-pc-windows-msvc.tar.xz": "c36613cf57407212d10d37b76e49a60ff42336e953cdff9e177283f530a83fc1",
|
||||
"2026-01-22/llvm-tools-nightly-x86_64-unknown-linux-gnu.tar.xz": "0b123c5027dbd833aae6845ffe9bd07d309bf798746a7176aadaea68fbcbd05d",
|
||||
"2026-01-22/llvm-tools-nightly-x86_64-apple-darwin.tar.xz": "a47864491ad5619158c950ab7570fb6e487d5117338585c27334d45824b406d8",
|
||||
"2026-01-22/llvm-tools-nightly-aarch64-apple-darwin.tar.xz": "db9bc826d6e2e7e914505d50157682e516ceb90357e83d77abddc32c2d962f41",
|
||||
"2026-01-22/llvm-tools-nightly-x86_64-pc-windows-msvc.tar.xz": "ffaa406932b2fe62e01dad61cf4ed34860a5d2a6f9306ca340d79e630d930039",
|
||||
"2026-01-22/rust-std-nightly-x86_64-unknown-linux-gnu.tar.xz": "e9c0d5e06e18a4b509391b3088f29293e310cdc8ccc865be8fa3f09733326925",
|
||||
"2026-01-22/rust-std-nightly-x86_64-apple-darwin.tar.xz": "25d75995cee679a4828ca9fe48c5a31a67c3b0846018440ef912e5a6208f53f6",
|
||||
"2026-01-22/rust-std-nightly-aarch64-apple-darwin.tar.xz": "e4132bf3f2eed4684c86756a02315bcf481c23e675e3e25630fc604c9cb4594c",
|
||||
"2026-01-22/rust-std-nightly-x86_64-pc-windows-msvc.tar.xz": "961bb535ef95ae8a5fa4e224cb94aff190f155c45a9bcf7a53e184b024aa41b1",
|
||||
"2025-08-01/rustc-nightly-x86_64-unknown-linux-gnu.tar.xz": "9bbeaf5d3fc7247d31463a9083aa251c995cc50662c8219e7a2254d76a72a9a4",
|
||||
"2025-08-01/rustc-nightly-x86_64-apple-darwin.tar.xz": "c9ea539a8eff0d5d162701f99f9e1aabe14dd0dfb420d62362817a5d09219de7",
|
||||
"2025-08-01/rustc-nightly-aarch64-apple-darwin.tar.xz": "ae83feebbc39cfd982e4ecc8297731fe79c185173aee138467b334c5404b3773",
|
||||
"2025-08-01/rustc-nightly-x86_64-pc-windows-msvc.tar.xz": "9f170c30d802a349be60cf52ec46260802093cb1013ad667fc0d528b7b10152f",
|
||||
"2025-08-01/clippy-nightly-x86_64-unknown-linux-gnu.tar.xz": "9ae5f3cd8f557c4f6df522597c69d14398cf604cfaed2b83e767c4b77a7eaaf6",
|
||||
"2025-08-01/clippy-nightly-x86_64-apple-darwin.tar.xz": "983cb9ee0b6b968188e04ab2d33743d54764b2681ce565e1b3f2b9135c696a3e",
|
||||
"2025-08-01/clippy-nightly-aarch64-apple-darwin.tar.xz": "ed2219dbc49d088225e1b7c5c4390fa295066e071fddaa2714018f6bb39ddbf0",
|
||||
"2025-08-01/clippy-nightly-x86_64-pc-windows-msvc.tar.xz": "911f40ab5cbdd686f40e00965271fe47c4805513a308ed01f30eafb25b448a50",
|
||||
"2025-08-01/cargo-nightly-x86_64-unknown-linux-gnu.tar.xz": "106463c284e48e4904c717471eeec2be5cc83a9d2cae8d6e948b52438cad2e69",
|
||||
"2025-08-01/cargo-nightly-x86_64-apple-darwin.tar.xz": "6ad35c40efc41a8c531ea43235058347b6902d98a9693bf0aed7fc16d5590cef",
|
||||
"2025-08-01/cargo-nightly-aarch64-apple-darwin.tar.xz": "dd28c365e9d298abc3154c797720ad36a0058f131265c9978b4c8e4e37012c8a",
|
||||
"2025-08-01/cargo-nightly-x86_64-pc-windows-msvc.tar.xz": "7b431286e12d6b3834b038f078389a00cac73f351e8c3152b2504a3c06420b3b",
|
||||
"2025-08-01/llvm-tools-nightly-x86_64-unknown-linux-gnu.tar.xz": "e342e305d7927cc288d386983b2bc253cfad3776b113386e903d0b302648ef47",
|
||||
"2025-08-01/llvm-tools-nightly-x86_64-apple-darwin.tar.xz": "e44dd3506524d85c37b3a54bcc91d01378fd2c590b2db5c5974d12f05c1b84d1",
|
||||
"2025-08-01/llvm-tools-nightly-aarch64-apple-darwin.tar.xz": "0c1b5f46dd81be4a9227b10283a0fcaa39c14fea7e81aea6fd6d9887ff6cdc41",
|
||||
"2025-08-01/llvm-tools-nightly-x86_64-pc-windows-msvc.tar.xz": "423e5fd11406adccbc31b8456ceb7375ce055cdf45e90d2c3babeb2d7f58383f",
|
||||
"2025-08-01/rust-std-nightly-x86_64-unknown-linux-gnu.tar.xz": "3c0ceb46a252647a1d4c7116d9ccae684fa5e42aaf3296419febd2c962c3b41d",
|
||||
"2025-08-01/rust-std-nightly-x86_64-apple-darwin.tar.xz": "3be416003cab10f767390a753d1d16ae4d26c7421c03c98992cf1943e5b0efe8",
|
||||
"2025-08-01/rust-std-nightly-aarch64-apple-darwin.tar.xz": "4046ac0ef951cb056b5028a399124f60999fa37792eab69d008d8d7965f389b4",
|
||||
"2025-08-01/rust-std-nightly-x86_64-pc-windows-msvc.tar.xz": "191ed9d8603c3a4fe5a7bbbc2feb72049078dae2df3d3b7d5dedf3abbf823e6e",
|
||||
},
|
||||
versions = [RUST_VERSION],
|
||||
)
|
||||
@@ -190,15 +188,6 @@ pip.parse(
|
||||
)
|
||||
use_repo(pip, "codegen_deps")
|
||||
|
||||
python = use_extension("@rules_python//python/extensions:python.bzl", "python")
|
||||
python.toolchain(
|
||||
is_default = True,
|
||||
python_version = "3.12",
|
||||
)
|
||||
use_repo(python, "python_3_12", "python_versions")
|
||||
|
||||
register_toolchains("@python_versions//3.12:all")
|
||||
|
||||
swift_deps = use_extension("//swift/third_party:load.bzl", "swift_deps")
|
||||
|
||||
# following list can be kept in sync with `bazel mod tidy`
|
||||
@@ -265,11 +254,11 @@ use_repo(
|
||||
)
|
||||
|
||||
go_sdk = use_extension("@rules_go//go:extensions.bzl", "go_sdk")
|
||||
go_sdk.download(version = "1.26.0")
|
||||
go_sdk.download(version = "1.25.0")
|
||||
|
||||
go_deps = use_extension("@gazelle//:extensions.bzl", "go_deps")
|
||||
go_deps.from_file(go_mod = "//go/extractor:go.mod")
|
||||
use_repo(go_deps, "com_github_stretchr_testify", "org_golang_x_mod", "org_golang_x_tools")
|
||||
use_repo(go_deps, "org_golang_x_mod", "org_golang_x_tools")
|
||||
|
||||
ripunzip_archive = use_repo_rule("//misc/ripunzip:ripunzip.bzl", "ripunzip_archive")
|
||||
|
||||
|
||||
@@ -1,11 +1,3 @@
|
||||
## 0.4.29
|
||||
|
||||
No user-facing changes.
|
||||
|
||||
## 0.4.28
|
||||
|
||||
No user-facing changes.
|
||||
|
||||
## 0.4.27
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
## 0.4.28
|
||||
|
||||
No user-facing changes.
|
||||
@@ -1,3 +0,0 @@
|
||||
## 0.4.29
|
||||
|
||||
No user-facing changes.
|
||||
@@ -1,2 +1,2 @@
|
||||
---
|
||||
lastReleaseVersion: 0.4.29
|
||||
lastReleaseVersion: 0.4.27
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
name: codeql/actions-all
|
||||
version: 0.4.30-dev
|
||||
version: 0.4.27
|
||||
library: true
|
||||
warnOnImplicitThis: true
|
||||
dependencies:
|
||||
|
||||
@@ -1,11 +1,3 @@
|
||||
## 0.6.21
|
||||
|
||||
No user-facing changes.
|
||||
|
||||
## 0.6.20
|
||||
|
||||
No user-facing changes.
|
||||
|
||||
## 0.6.19
|
||||
|
||||
No user-facing changes.
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
## 0.6.20
|
||||
|
||||
No user-facing changes.
|
||||
@@ -1,3 +0,0 @@
|
||||
## 0.6.21
|
||||
|
||||
No user-facing changes.
|
||||
@@ -1,2 +1,2 @@
|
||||
---
|
||||
lastReleaseVersion: 0.6.21
|
||||
lastReleaseVersion: 0.6.19
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
name: codeql/actions-queries
|
||||
version: 0.6.22-dev
|
||||
version: 0.6.19
|
||||
library: false
|
||||
warnOnImplicitThis: true
|
||||
groups: [actions, queries]
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,5 +0,0 @@
|
||||
description: Add trap_filename, source_file_uses_trap and in_trap relations
|
||||
compatibility: full
|
||||
trap_filename.rel: delete
|
||||
source_file_uses_trap.rel: delete
|
||||
in_trap.rel: delete
|
||||
@@ -1,24 +1,3 @@
|
||||
## 8.0.0
|
||||
|
||||
### Breaking Changes
|
||||
|
||||
* CodeQL version 2.24.2 accidentally introduced a syntactical breaking change to `BarrierGuard<...>::getAnIndirectBarrierNode` and `InstructionBarrierGuard<...>::getAnIndirectBarrierNode`. These breaking changes have now been reverted so that the original code compiles again.
|
||||
* `MustFlow`, the inter-procedural must-flow data flow analysis library, has been re-worked to use parameterized modules. Like in the case of data flow and taint tracking, instead of extending the `MustFlowConfiguration` class, the user should now implement a module with the `MustFlow::ConfigSig` signature, and instantiate the `MustFlow::Global` parameterized module with the implemented module.
|
||||
|
||||
### Minor Analysis Improvements
|
||||
|
||||
* Refactored the "Year field changed using an arithmetic operation without checking for leap year" query (`cpp/leap-year/unchecked-after-arithmetic-year-modification`) to address large numbers of false positive results.
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* The `allowInterproceduralFlow` predicate of must-flow data flow configurations now correctly handles direct recursion.
|
||||
|
||||
## 7.1.1
|
||||
|
||||
### Minor Analysis Improvements
|
||||
|
||||
* Added remote flow source models for the `winhttp.h` windows header and the Azure SDK core library for C/C++.
|
||||
|
||||
## 7.1.0
|
||||
|
||||
### New Features
|
||||
|
||||
@@ -1,5 +0,0 @@
|
||||
## 7.1.1
|
||||
|
||||
### Minor Analysis Improvements
|
||||
|
||||
* Added remote flow source models for the `winhttp.h` windows header and the Azure SDK core library for C/C++.
|
||||
@@ -1,14 +0,0 @@
|
||||
## 8.0.0
|
||||
|
||||
### Breaking Changes
|
||||
|
||||
* CodeQL version 2.24.2 accidentally introduced a syntactical breaking change to `BarrierGuard<...>::getAnIndirectBarrierNode` and `InstructionBarrierGuard<...>::getAnIndirectBarrierNode`. These breaking changes have now been reverted so that the original code compiles again.
|
||||
* `MustFlow`, the inter-procedural must-flow data flow analysis library, has been re-worked to use parameterized modules. Like in the case of data flow and taint tracking, instead of extending the `MustFlowConfiguration` class, the user should now implement a module with the `MustFlow::ConfigSig` signature, and instantiate the `MustFlow::Global` parameterized module with the implemented module.
|
||||
|
||||
### Minor Analysis Improvements
|
||||
|
||||
* Refactored the "Year field changed using an arithmetic operation without checking for leap year" query (`cpp/leap-year/unchecked-after-arithmetic-year-modification`) to address large numbers of false positive results.
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* The `allowInterproceduralFlow` predicate of must-flow data flow configurations now correctly handles direct recursion.
|
||||
@@ -1,2 +1,2 @@
|
||||
---
|
||||
lastReleaseVersion: 8.0.0
|
||||
lastReleaseVersion: 7.1.0
|
||||
|
||||
@@ -24,13 +24,6 @@ extensions:
|
||||
- ["", "", False, "MapViewOfFileNuma2", "", "", "ReturnValue[*]", "local", "manual"]
|
||||
# ntifs.h
|
||||
- ["", "", False, "NtReadFile", "", "", "Argument[*5]", "local", "manual"]
|
||||
# winhttp.h
|
||||
- ["", "", False, "WinHttpReadData", "", "", "Argument[*1]", "remote", "manual"]
|
||||
- ["", "", False, "WinHttpReadDataEx", "", "", "Argument[*1]", "remote", "manual"]
|
||||
- ["", "", False, "WinHttpQueryHeaders", "", "", "Argument[*3]", "remote", "manual"]
|
||||
- ["", "", False, "WinHttpQueryHeadersEx", "", "", "Argument[*5]", "remote", "manual"]
|
||||
- ["", "", False, "WinHttpQueryHeadersEx", "", "", "Argument[*6]", "remote", "manual"]
|
||||
- ["", "", False, "WinHttpQueryHeadersEx", "", "", "Argument[**8]", "remote", "manual"]
|
||||
- addsTo:
|
||||
pack: codeql/cpp-all
|
||||
extensible: summaryModel
|
||||
@@ -53,6 +46,4 @@ extensions:
|
||||
- ["", "", False, "RtlMoveMemory", "", "", "Argument[*@1]", "Argument[*@0]", "value", "manual"]
|
||||
- ["", "", False, "RtlMoveVolatileMemory", "", "", "Argument[*@1]", "Argument[*@0]", "value", "manual"]
|
||||
# winternl.h
|
||||
- ["", "", False, "RtlInitUnicodeString", "", "", "Argument[*1]", "Argument[*0].Field[*Buffer]", "value", "manual"]
|
||||
# winhttp.h
|
||||
- ["", "", False, "WinHttpCrackUrl", "", "", "Argument[*0]", "Argument[*3]", "taint", "manual"]
|
||||
- ["", "", False, "RtlInitUnicodeString", "", "", "Argument[*1]", "Argument[*0].Field[*Buffer]", "value", "manual"]
|
||||
@@ -1,41 +0,0 @@
|
||||
extensions:
|
||||
- addsTo:
|
||||
pack: codeql/cpp-all
|
||||
extensible: sourceModel
|
||||
data: # namespace, type, subtypes, name, signature, ext, output, kind, provenance
|
||||
- ["Azure::Core::Http", "RawResponse", True, "GetHeaders", "", "", "ReturnValue[*]", "remote", "manual"]
|
||||
- ["Azure::Core::Http", "RawResponse", True, "GetBody", "", "", "ReturnValue[*]", "remote", "manual"]
|
||||
- ["Azure::Core::Http", "RawResponse", True, "ExtractBodyStream", "", "", "ReturnValue[*]", "remote", "manual"]
|
||||
- ["Azure::Core::Http", "Request", True, "GetHeaders", "", "", "ReturnValue", "remote", "manual"]
|
||||
- ["Azure::Core::Http", "Request", True, "GetHeader", "", "", "ReturnValue", "remote", "manual"]
|
||||
- ["Azure::Core::Http", "Request", True, "GetBodyStream", "", "", "ReturnValue[*]", "remote", "manual"]
|
||||
|
||||
- addsTo:
|
||||
pack: codeql/cpp-all
|
||||
extensible: summaryModel
|
||||
data: # namespace, type, subtypes, name, signature, ext, input, output, kind, provenance
|
||||
- ["Azure::Core", "Url", True, "Url", "", "", "Argument[*0]", "Argument[-1]", "taint", "manual"]
|
||||
- ["Azure::Core", "Url", True, "SetScheme", "", "", "Argument[*0]", "Argument[-1]", "taint", "manual"]
|
||||
- ["Azure::Core", "Url", True, "SetHost", "", "", "Argument[*0]", "Argument[-1]", "taint", "manual"]
|
||||
- ["Azure::Core", "Url", True, "SetPort", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"]
|
||||
- ["Azure::Core", "Url", True, "SetPath", "", "", "Argument[*0]", "Argument[-1]", "taint", "manual"]
|
||||
- ["Azure::Core", "Url", True, "SetQueryParameters", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"]
|
||||
- ["Azure::Core", "Url", True, "AppendPath", "", "", "Argument[*0]", "Argument[-1]", "taint", "manual"]
|
||||
- ["Azure::Core", "Url", True, "AppendQueryParameter", "", "", "Argument[*1]", "Argument[-1]", "taint", "manual"]
|
||||
- ["Azure::Core", "Url", True, "GetHost", "", "", "Argument[-1]", "ReturnValue[*]", "taint", "manual"]
|
||||
- ["Azure::Core", "Url", True, "GetPath", "", "", "Argument[-1]", "ReturnValue[*]", "taint", "manual"]
|
||||
- ["Azure::Core", "Url", True, "GetPort", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"]
|
||||
- ["Azure::Core", "Url", True, "GetQueryParameters", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"]
|
||||
- ["Azure::Core", "Url", True, "GetScheme", "", "", "Argument[-1]", "ReturnValue[*]", "taint", "manual"]
|
||||
- ["Azure::Core", "Url", True, "GetRelativeUrl", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"]
|
||||
- ["Azure::Core", "Url", True, "GetAbsoluteUrl", "", "", "Argument[-1]", "ReturnValue", "taint", "manual"]
|
||||
- ["Azure::Core", "Url", True, "Decode", "", "", "Argument[*0]", "ReturnValue", "taint", "manual"]
|
||||
- ["Azure::Core", "Url", True, "Encode", "", "", "Argument[*0]", "ReturnValue", "taint", "manual"]
|
||||
- ["Azure::Core::IO", "BodyStream", True, "Read", "", "", "Argument[-1]", "Argument[*0]", "taint", "manual"]
|
||||
- ["Azure::Core::IO", "BodyStream", True, "ReadToCount", "", "", "Argument[-1]", "Argument[*0]", "taint", "manual"]
|
||||
- ["Azure::Core::IO", "BodyStream", True, "ReadToEnd", "", "", "Argument[-1]", "ReturnValue.Element", "taint", "manual"]
|
||||
- ["Azure", "Nullable", True, "Nullable", "", "", "Argument[0]", "Argument[-1]", "taint", "manual"]
|
||||
- ["Azure", "Nullable", True, "operator=", "", "", "Argument[*0]", "Argument[-1]", "value", "manual"]
|
||||
- ["Azure", "Nullable", True, "Value", "", "", "Argument[-1]", "ReturnValue[*]", "taint", "manual"]
|
||||
- ["Azure", "Nullable", True, "operator->", "", "", "Argument[-1]", "ReturnValue[*]", "taint", "manual"]
|
||||
- ["Azure", "Nullable", True, "operator*", "", "", "Argument[-1]", "ReturnValue[*]", "taint", "manual"]
|
||||
@@ -1,5 +1,5 @@
|
||||
name: codeql/cpp-all
|
||||
version: 8.0.1-dev
|
||||
version: 7.1.0
|
||||
groups: cpp
|
||||
dbscheme: semmlecode.cpp.dbscheme
|
||||
extractor: cpp
|
||||
|
||||
@@ -14,9 +14,7 @@ class PackedTimeType extends Type {
|
||||
}
|
||||
}
|
||||
|
||||
private predicate timeType(string typeName) {
|
||||
typeName = ["_SYSTEMTIME", "SYSTEMTIME", "tm", "TIME_FIELDS", "_TIME_FIELDS", "PTIME_FIELDS"]
|
||||
}
|
||||
private predicate timeType(string typeName) { typeName = ["_SYSTEMTIME", "SYSTEMTIME", "tm"] }
|
||||
|
||||
/**
|
||||
* A type that is used to represent times and dates in an 'unpacked' form, that is,
|
||||
@@ -97,24 +95,3 @@ class StructTmMonthFieldAccess extends MonthFieldAccess {
|
||||
class StructTmYearFieldAccess extends YearFieldAccess {
|
||||
StructTmYearFieldAccess() { this.getTarget().getName() = "tm_year" }
|
||||
}
|
||||
|
||||
/**
|
||||
* A `DayFieldAccess` for the `TIME_FIELDS` struct.
|
||||
*/
|
||||
class TimeFieldsDayFieldAccess extends DayFieldAccess {
|
||||
TimeFieldsDayFieldAccess() { this.getTarget().getName() = "Day" }
|
||||
}
|
||||
|
||||
/**
|
||||
* A `MonthFieldAccess` for the `TIME_FIELDS` struct.
|
||||
*/
|
||||
class TimeFieldsMonthFieldAccess extends MonthFieldAccess {
|
||||
TimeFieldsMonthFieldAccess() { this.getTarget().getName() = "Month" }
|
||||
}
|
||||
|
||||
/**
|
||||
* A `YearFieldAccess` for the `TIME_FIELDS` struct.
|
||||
*/
|
||||
class TimeFieldsYearFieldAccess extends YearFieldAccess {
|
||||
TimeFieldsYearFieldAccess() { this.getTarget().getName() = "Year" }
|
||||
}
|
||||
|
||||
@@ -34,38 +34,6 @@ private string getSingleLocationFilePath(@element e) {
|
||||
macroinvocations(e, _, loc, _)
|
||||
or
|
||||
preprocdirects(e, _, loc)
|
||||
or
|
||||
diagnostics(e, _, _, _, _, loc)
|
||||
or
|
||||
usings(e, _, loc, _)
|
||||
or
|
||||
static_asserts(e, _, _, loc, _)
|
||||
or
|
||||
derivations(e, _, _, _, loc)
|
||||
or
|
||||
frienddecls(e, _, _, loc)
|
||||
or
|
||||
comments(e, _, loc)
|
||||
or
|
||||
exprs(e, _, loc)
|
||||
or
|
||||
stmts(e, _, loc)
|
||||
or
|
||||
initialisers(e, _, _, loc)
|
||||
or
|
||||
attributes(e, _, _, _, loc)
|
||||
or
|
||||
attribute_args(e, _, _, _, loc)
|
||||
or
|
||||
namequalifiers(e, _, _, loc)
|
||||
or
|
||||
enumconstants(e, _, _, _, _, loc)
|
||||
or
|
||||
type_mentions(e, _, loc, _)
|
||||
or
|
||||
lambda_capture(e, _, _, _, _, _, loc)
|
||||
or
|
||||
concept_templates(e, _, loc)
|
||||
|
|
||||
result = getLocationFilePath(loc)
|
||||
)
|
||||
@@ -96,27 +64,17 @@ private string getMultiLocationFilePath(@element e) {
|
||||
overlay[local]
|
||||
private predicate isBase() { not isOverlay() }
|
||||
|
||||
/**
|
||||
* Holds if `path` was extracted in the overlay database.
|
||||
*/
|
||||
overlay[local]
|
||||
private predicate overlayHasFile(string path) {
|
||||
isOverlay() and
|
||||
files(_, path) and
|
||||
path != ""
|
||||
}
|
||||
|
||||
/**
|
||||
* Discards an element from the base variant if:
|
||||
* - It has a single location in a file extracted in the overlay, or
|
||||
* - All of its locations are in files extracted in the overlay.
|
||||
* - It has a single location in a changed file, or
|
||||
* - All of its locations are in changed files.
|
||||
*/
|
||||
overlay[discard_entity]
|
||||
private predicate discardElement(@element e) {
|
||||
isBase() and
|
||||
(
|
||||
overlayHasFile(getSingleLocationFilePath(e))
|
||||
overlayChangedFiles(getSingleLocationFilePath(e))
|
||||
or
|
||||
forex(string path | path = getMultiLocationFilePath(e) | overlayHasFile(path))
|
||||
forex(string path | path = getMultiLocationFilePath(e) | overlayChangedFiles(path))
|
||||
)
|
||||
}
|
||||
|
||||
@@ -8,145 +8,83 @@ private import cpp
|
||||
private import semmle.code.cpp.ir.IR
|
||||
|
||||
/**
|
||||
* Provides an inter-procedural must-flow data flow analysis.
|
||||
* A configuration of a data flow analysis that performs must-flow analysis. This is different
|
||||
* from `DataFlow.qll` which performs may-flow analysis (i.e., it finds paths where the source _may_
|
||||
* flow to the sink).
|
||||
*
|
||||
* Like in `DataFlow.qll`, each use of the `MustFlow.qll` library must define its own unique extension
|
||||
* of this abstract class. To create a configuration, extend this class with a subclass whose
|
||||
* characteristic predicate is a unique singleton string and override `isSource`, `isSink` (and
|
||||
* `isAdditionalFlowStep` if additional steps are required).
|
||||
*/
|
||||
module MustFlow {
|
||||
/**
|
||||
* An input configuration of a data flow analysis that performs must-flow analysis. This is different
|
||||
* from `DataFlow.qll` which performs may-flow analysis (i.e., it finds paths where the source _may_
|
||||
* flow to the sink).
|
||||
*/
|
||||
signature module ConfigSig {
|
||||
/**
|
||||
* Holds if `source` is a relevant data flow source.
|
||||
*/
|
||||
predicate isSource(Instruction source);
|
||||
|
||||
/**
|
||||
* Holds if `sink` is a relevant data flow sink.
|
||||
*/
|
||||
predicate isSink(Operand sink);
|
||||
|
||||
/**
|
||||
* Holds if data flow through `instr` is prohibited.
|
||||
*/
|
||||
default predicate isBarrier(Instruction instr) { none() }
|
||||
|
||||
/**
|
||||
* Holds if the additional flow step from `node1` to `node2` must be taken
|
||||
* into account in the analysis.
|
||||
*/
|
||||
default predicate isAdditionalFlowStep(Operand node1, Instruction node2) { none() }
|
||||
|
||||
/** Holds if this configuration allows flow from arguments to parameters. */
|
||||
default predicate allowInterproceduralFlow() { any() }
|
||||
}
|
||||
abstract class MustFlowConfiguration extends string {
|
||||
bindingset[this]
|
||||
MustFlowConfiguration() { any() }
|
||||
|
||||
/**
|
||||
* Constructs a global must-flow computation.
|
||||
* Holds if `source` is a relevant data flow source.
|
||||
*/
|
||||
module Global<ConfigSig Config> {
|
||||
import Config
|
||||
abstract predicate isSource(Instruction source);
|
||||
|
||||
/**
|
||||
* Holds if data must flow from `source` to `sink`.
|
||||
*
|
||||
* The corresponding paths are generated from the end-points and the graph
|
||||
* included in the module `PathGraph`.
|
||||
*/
|
||||
predicate flowPath(PathNode source, PathSink sink) {
|
||||
isSource(source.getInstruction()) and
|
||||
source.getASuccessor*() = sink
|
||||
}
|
||||
/**
|
||||
* Holds if `sink` is a relevant data flow sink.
|
||||
*/
|
||||
abstract predicate isSink(Operand sink);
|
||||
|
||||
/** Holds if `node` flows from a source. */
|
||||
pragma[nomagic]
|
||||
private predicate flowsFromSource(Instruction node) {
|
||||
not isBarrier(node) and
|
||||
(
|
||||
isSource(node)
|
||||
or
|
||||
exists(Instruction mid |
|
||||
step(mid, node) and
|
||||
flowsFromSource(mid)
|
||||
)
|
||||
)
|
||||
}
|
||||
/**
|
||||
* Holds if data flow through `instr` is prohibited.
|
||||
*/
|
||||
predicate isBarrier(Instruction instr) { none() }
|
||||
|
||||
/** Holds if `node` flows to a sink. */
|
||||
pragma[nomagic]
|
||||
private predicate flowsToSink(Instruction node) {
|
||||
flowsFromSource(node) and
|
||||
(
|
||||
isSink(node.getAUse())
|
||||
or
|
||||
exists(Instruction mid |
|
||||
step(node, mid) and
|
||||
flowsToSink(mid)
|
||||
)
|
||||
)
|
||||
}
|
||||
/**
|
||||
* Holds if the additional flow step from `node1` to `node2` must be taken
|
||||
* into account in the analysis.
|
||||
*/
|
||||
predicate isAdditionalFlowStep(Operand node1, Instruction node2) { none() }
|
||||
|
||||
/** Holds if `nodeFrom` flows to `nodeTo`. */
|
||||
private predicate step(Instruction nodeFrom, Instruction nodeTo) {
|
||||
Cached::localStep(nodeFrom, nodeTo)
|
||||
or
|
||||
allowInterproceduralFlow() and
|
||||
Cached::flowThroughCallable(nodeFrom, nodeTo)
|
||||
or
|
||||
isAdditionalFlowStep(nodeFrom.getAUse(), nodeTo)
|
||||
}
|
||||
/** Holds if this configuration allows flow from arguments to parameters. */
|
||||
predicate allowInterproceduralFlow() { any() }
|
||||
|
||||
private newtype TLocalPathNode =
|
||||
MkLocalPathNode(Instruction n) {
|
||||
flowsToSink(n) and
|
||||
(
|
||||
isSource(n)
|
||||
or
|
||||
exists(PathNode mid | step(mid.getInstruction(), n))
|
||||
)
|
||||
}
|
||||
|
||||
/** A `Node` that is in a path from a source to a sink. */
|
||||
class PathNode extends TLocalPathNode {
|
||||
Instruction n;
|
||||
|
||||
PathNode() { this = MkLocalPathNode(n) }
|
||||
|
||||
/** Gets the underlying node. */
|
||||
Instruction getInstruction() { result = n }
|
||||
|
||||
/** Gets a textual representation of this node. */
|
||||
string toString() { result = n.getAst().toString() }
|
||||
|
||||
/** Gets the location of this element. */
|
||||
Location getLocation() { result = n.getLocation() }
|
||||
|
||||
/** Gets a successor node, if any. */
|
||||
PathNode getASuccessor() { step(this.getInstruction(), result.getInstruction()) }
|
||||
}
|
||||
|
||||
private class PathSink extends PathNode {
|
||||
PathSink() { isSink(this.getInstruction().getAUse()) }
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides the query predicates needed to include a graph in a path-problem query.
|
||||
*/
|
||||
module PathGraph {
|
||||
private predicate reach(PathNode n) { n instanceof PathSink or reach(n.getASuccessor()) }
|
||||
|
||||
/** Holds if `(a,b)` is an edge in the graph of data flow path explanations. */
|
||||
query predicate edges(PathNode a, PathNode b) { a.getASuccessor() = b and reach(b) }
|
||||
|
||||
/** Holds if `n` is a node in the graph of data flow path explanations. */
|
||||
query predicate nodes(PathNode n, string key, string val) {
|
||||
reach(n) and key = "semmle.label" and val = n.toString()
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Holds if data must flow from `source` to `sink` for this configuration.
|
||||
*
|
||||
* The corresponding paths are generated from the end-points and the graph
|
||||
* included in the module `PathGraph`.
|
||||
*/
|
||||
final predicate hasFlowPath(MustFlowPathNode source, MustFlowPathSink sink) {
|
||||
this.isSource(source.getInstruction()) and
|
||||
source.getASuccessor*() = sink
|
||||
}
|
||||
}
|
||||
|
||||
/** Holds if `node` flows from a source. */
|
||||
pragma[nomagic]
|
||||
private predicate flowsFromSource(Instruction node, MustFlowConfiguration config) {
|
||||
not config.isBarrier(node) and
|
||||
(
|
||||
config.isSource(node)
|
||||
or
|
||||
exists(Instruction mid |
|
||||
step(mid, node, config) and
|
||||
flowsFromSource(mid, pragma[only_bind_into](config))
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
/** Holds if `node` flows to a sink. */
|
||||
pragma[nomagic]
|
||||
private predicate flowsToSink(Instruction node, MustFlowConfiguration config) {
|
||||
flowsFromSource(node, pragma[only_bind_into](config)) and
|
||||
(
|
||||
config.isSink(node.getAUse())
|
||||
or
|
||||
exists(Instruction mid |
|
||||
step(node, mid, config) and
|
||||
flowsToSink(mid, pragma[only_bind_into](config))
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
cached
|
||||
private module Cached {
|
||||
/** Holds if `p` is the `n`'th parameter of the non-virtual function `f`. */
|
||||
@@ -164,7 +102,7 @@ private module Cached {
|
||||
not f.isVirtual() and
|
||||
call.getPositionalArgument(n) = instr and
|
||||
f = call.getStaticCallTarget() and
|
||||
isEnclosingNonVirtualFunctionInitializeParameter(init, f) and
|
||||
getEnclosingNonVirtualFunctionInitializeParameter(init, f) and
|
||||
init.getParameter().getIndex() = pragma[only_bind_into](pragma[only_bind_out](n))
|
||||
}
|
||||
|
||||
@@ -173,7 +111,7 @@ private module Cached {
|
||||
* corresponding initialization instruction that receives the value of `instr` in `f`.
|
||||
*/
|
||||
pragma[noinline]
|
||||
private predicate isPositionalArgumentInitParam(
|
||||
private predicate getPositionalArgumentInitParam(
|
||||
CallInstruction call, Instruction instr, InitializeParameterInstruction init, Function f
|
||||
) {
|
||||
exists(int n |
|
||||
@@ -188,18 +126,18 @@ private module Cached {
|
||||
* `instr` in `f`.
|
||||
*/
|
||||
pragma[noinline]
|
||||
private predicate isThisArgumentInitParam(
|
||||
private predicate getThisArgumentInitParam(
|
||||
CallInstruction call, Instruction instr, InitializeParameterInstruction init, Function f
|
||||
) {
|
||||
not f.isVirtual() and
|
||||
call.getStaticCallTarget() = f and
|
||||
isEnclosingNonVirtualFunctionInitializeParameter(init, f) and
|
||||
getEnclosingNonVirtualFunctionInitializeParameter(init, f) and
|
||||
call.getThisArgument() = instr and
|
||||
init.getIRVariable() instanceof IRThisVariable
|
||||
}
|
||||
|
||||
/** Holds if `f` is the enclosing non-virtual function of `init`. */
|
||||
private predicate isEnclosingNonVirtualFunctionInitializeParameter(
|
||||
private predicate getEnclosingNonVirtualFunctionInitializeParameter(
|
||||
InitializeParameterInstruction init, Function f
|
||||
) {
|
||||
not f.isVirtual() and
|
||||
@@ -207,7 +145,7 @@ private module Cached {
|
||||
}
|
||||
|
||||
/** Holds if `f` is the enclosing non-virtual function of `init`. */
|
||||
private predicate isEnclosingNonVirtualFunctionInitializeIndirection(
|
||||
private predicate getEnclosingNonVirtualFunctionInitializeIndirection(
|
||||
InitializeIndirectionInstruction init, Function f
|
||||
) {
|
||||
not f.isVirtual() and
|
||||
@@ -215,16 +153,15 @@ private module Cached {
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if `argument` is an argument (or argument indirection) to a call, and
|
||||
* `parameter` is the corresponding initialization instruction in the call target.
|
||||
* Holds if `instr` is an argument (or argument indirection) to a call, and
|
||||
* `succ` is the corresponding initialization instruction in the call target.
|
||||
*/
|
||||
cached
|
||||
predicate flowThroughCallable(Instruction argument, Instruction parameter) {
|
||||
private predicate flowThroughCallable(Instruction argument, Instruction parameter) {
|
||||
// Flow from an argument to a parameter
|
||||
exists(CallInstruction call, InitializeParameterInstruction init | init = parameter |
|
||||
isPositionalArgumentInitParam(call, argument, init, call.getStaticCallTarget())
|
||||
getPositionalArgumentInitParam(call, argument, init, call.getStaticCallTarget())
|
||||
or
|
||||
isThisArgumentInitParam(call, argument, init, call.getStaticCallTarget())
|
||||
getThisArgumentInitParam(call, argument, init, call.getStaticCallTarget())
|
||||
)
|
||||
or
|
||||
// Flow from argument indirection to parameter indirection
|
||||
@@ -233,7 +170,7 @@ private module Cached {
|
||||
|
|
||||
init = parameter and
|
||||
read.getPrimaryInstruction() = call and
|
||||
isEnclosingNonVirtualFunctionInitializeIndirection(init, call.getStaticCallTarget())
|
||||
getEnclosingNonVirtualFunctionInitializeIndirection(init, call.getStaticCallTarget())
|
||||
|
|
||||
exists(int n |
|
||||
read.getSideEffectOperand().getAnyDef() = argument and
|
||||
@@ -268,10 +205,92 @@ private module Cached {
|
||||
}
|
||||
|
||||
cached
|
||||
predicate localStep(Instruction nodeFrom, Instruction nodeTo) {
|
||||
predicate step(Instruction nodeFrom, Instruction nodeTo) {
|
||||
exists(Operand mid |
|
||||
instructionToOperandStep(nodeFrom, mid) and
|
||||
operandToInstructionStep(mid, nodeTo)
|
||||
)
|
||||
or
|
||||
flowThroughCallable(nodeFrom, nodeTo)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the enclosing callable of `n`. Unlike `n.getEnclosingCallable()`, this
|
||||
* predicate ensures that joins go from `n` to the result instead of the other
|
||||
* way around.
|
||||
*/
|
||||
pragma[inline]
|
||||
private IRFunction getEnclosingCallable(Instruction n) {
|
||||
pragma[only_bind_into](result) = pragma[only_bind_out](n).getEnclosingIRFunction()
|
||||
}
|
||||
|
||||
/** Holds if `nodeFrom` flows to `nodeTo`. */
|
||||
private predicate step(Instruction nodeFrom, Instruction nodeTo, MustFlowConfiguration config) {
|
||||
exists(config) and
|
||||
Cached::step(pragma[only_bind_into](nodeFrom), pragma[only_bind_into](nodeTo)) and
|
||||
(
|
||||
config.allowInterproceduralFlow()
|
||||
or
|
||||
getEnclosingCallable(nodeFrom) = getEnclosingCallable(nodeTo)
|
||||
)
|
||||
or
|
||||
config.isAdditionalFlowStep(nodeFrom.getAUse(), nodeTo)
|
||||
}
|
||||
|
||||
private newtype TLocalPathNode =
|
||||
MkLocalPathNode(Instruction n, MustFlowConfiguration config) {
|
||||
flowsToSink(n, config) and
|
||||
(
|
||||
config.isSource(n)
|
||||
or
|
||||
exists(MustFlowPathNode mid | step(mid.getInstruction(), n, config))
|
||||
)
|
||||
}
|
||||
|
||||
/** A `Node` that is in a path from a source to a sink. */
|
||||
class MustFlowPathNode extends TLocalPathNode {
|
||||
Instruction n;
|
||||
|
||||
MustFlowPathNode() { this = MkLocalPathNode(n, _) }
|
||||
|
||||
/** Gets the underlying node. */
|
||||
Instruction getInstruction() { result = n }
|
||||
|
||||
/** Gets a textual representation of this node. */
|
||||
string toString() { result = n.getAst().toString() }
|
||||
|
||||
/** Gets the location of this element. */
|
||||
Location getLocation() { result = n.getLocation() }
|
||||
|
||||
/** Gets a successor node, if any. */
|
||||
MustFlowPathNode getASuccessor() {
|
||||
step(this.getInstruction(), result.getInstruction(), this.getConfiguration())
|
||||
}
|
||||
|
||||
/** Gets the associated configuration. */
|
||||
MustFlowConfiguration getConfiguration() { this = MkLocalPathNode(_, result) }
|
||||
}
|
||||
|
||||
private class MustFlowPathSink extends MustFlowPathNode {
|
||||
MustFlowPathSink() { this.getConfiguration().isSink(this.getInstruction().getAUse()) }
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides the query predicates needed to include a graph in a path-problem query.
|
||||
*/
|
||||
module PathGraph {
|
||||
private predicate reach(MustFlowPathNode n) {
|
||||
n instanceof MustFlowPathSink or reach(n.getASuccessor())
|
||||
}
|
||||
|
||||
/** Holds if `(a,b)` is an edge in the graph of data flow path explanations. */
|
||||
query predicate edges(MustFlowPathNode a, MustFlowPathNode b) {
|
||||
a.getASuccessor() = b and reach(b)
|
||||
}
|
||||
|
||||
/** Holds if `n` is a node in the graph of data flow path explanations. */
|
||||
query predicate nodes(MustFlowPathNode n, string key, string val) {
|
||||
reach(n) and key = "semmle.label" and val = n.toString()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1726,7 +1726,9 @@ private module Cached {
|
||||
SsaImpl::ssaFlow(n, succ) and
|
||||
bb1 = n.getBasicBlock() and
|
||||
bb2 = succ.getBasicBlock() and
|
||||
bb2.strictlyDominates(bb1)
|
||||
bb1 != bb2 and
|
||||
bb2.dominates(bb1) and
|
||||
bb1.getASuccessor+() = bb2
|
||||
)
|
||||
}
|
||||
|
||||
@@ -2641,54 +2643,7 @@ module BarrierGuard<guardChecksSig/3 guardChecks> {
|
||||
exists(unit)
|
||||
}
|
||||
|
||||
private module P = ParameterizedBarrierGuard<Unit, guardChecks/4>;
|
||||
|
||||
predicate getABarrierNode = P::getABarrierNode/0;
|
||||
|
||||
/**
|
||||
* Gets an indirect expression node with indirection index `indirectionIndex` that is
|
||||
* safely guarded by the given guard check.
|
||||
*
|
||||
* For example, given the following code:
|
||||
* ```cpp
|
||||
* int* p;
|
||||
* // ...
|
||||
* *p = source();
|
||||
* if(is_safe_pointer(p)) {
|
||||
* sink(*p);
|
||||
* }
|
||||
* ```
|
||||
* and the following barrier guard check:
|
||||
* ```ql
|
||||
* predicate myGuardChecks(IRGuardCondition g, Expr e, boolean branch) {
|
||||
* exists(Call call |
|
||||
* g.getUnconvertedResultExpression() = call and
|
||||
* call.getTarget().hasName("is_safe_pointer") and
|
||||
* e = call.getAnArgument() and
|
||||
* branch = true
|
||||
* )
|
||||
* }
|
||||
* ```
|
||||
* implementing `isBarrier` as:
|
||||
* ```ql
|
||||
* predicate isBarrier(DataFlow::Node barrier) {
|
||||
* barrier = DataFlow::BarrierGuard<myGuardChecks/3>::getAnIndirectBarrierNode(1)
|
||||
* }
|
||||
* ```
|
||||
* will block flow from `x = source()` to `sink(x)`.
|
||||
*
|
||||
* NOTE: If a non-indirect expression is tracked, use `getABarrierNode` instead.
|
||||
*/
|
||||
Node getAnIndirectBarrierNode(int indirectionIndex) {
|
||||
result = P::getAnIndirectBarrierNode(indirectionIndex, _)
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets an indirect expression node that is safely guarded by the given guard check.
|
||||
*
|
||||
* See `getAnIndirectBarrierNode/1` for examples.
|
||||
*/
|
||||
Node getAnIndirectBarrierNode() { result = getAnIndirectBarrierNode(_) }
|
||||
import ParameterizedBarrierGuard<Unit, guardChecks/4>
|
||||
}
|
||||
|
||||
private module InstrWithParam<ParamSig P> {
|
||||
@@ -2799,20 +2754,7 @@ module InstructionBarrierGuard<instructionGuardChecksSig/3 instructionGuardCheck
|
||||
exists(unit)
|
||||
}
|
||||
|
||||
private module P = ParameterizedInstructionBarrierGuard<Unit, instructionGuardChecks/4>;
|
||||
|
||||
predicate getABarrierNode = P::getABarrierNode/0;
|
||||
|
||||
/**
|
||||
* Gets an indirect node with indirection index `indirectionIndex` that is
|
||||
* safely guarded by the given guard check.
|
||||
*/
|
||||
Node getAnIndirectBarrierNode(int indirectionIndex) {
|
||||
result = P::getAnIndirectBarrierNode(indirectionIndex, _)
|
||||
}
|
||||
|
||||
/** Gets an indirect node that is safely guarded by the given guard check. */
|
||||
Node getAnIndirectBarrierNode() { result = getAnIndirectBarrierNode(_) }
|
||||
import ParameterizedInstructionBarrierGuard<Unit, instructionGuardChecks/4>
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -62,12 +62,26 @@ private predicate ignoreConstantValue(Operation op) {
|
||||
op instanceof BitwiseXorExpr
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if `expr` contains an address-of expression that EDG may have constant-folded.
|
||||
* We don't recurse into `sizeof` or `alignof` since they don't evaluate their operands,
|
||||
* so any address-of inside them doesn't affect actual execution.
|
||||
*/
|
||||
private predicate containsAddressOf(Expr expr) {
|
||||
expr instanceof AddressOfExpr
|
||||
or
|
||||
not expr instanceof SizeofOperator and
|
||||
not expr instanceof AlignofOperator and
|
||||
containsAddressOf(expr.getAChild())
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if `expr` is a constant of a type that can be replaced directly with
|
||||
* its value in the IR. This does not include address constants as we have no
|
||||
* means to express those as QL values.
|
||||
*/
|
||||
predicate isIRConstant(Expr expr) {
|
||||
not containsAddressOf(expr) and
|
||||
exists(expr.getValue()) and
|
||||
// We avoid constant folding certain operations since it's often useful to
|
||||
// mark one of those as a source in dataflow, and if the operation is
|
||||
|
||||
@@ -390,7 +390,7 @@ class TranslatedDeclStmt extends TranslatedStmt {
|
||||
|
||||
override TranslatedElement getLastChild() { result = this.getChild(this.getChildCount() - 1) }
|
||||
|
||||
private int getChildCount() { result = count(int i | exists(this.getDeclarationEntry(i))) }
|
||||
private int getChildCount() { result = count(this.getDeclarationEntry(_)) }
|
||||
|
||||
IRDeclarationEntry getIRDeclarationEntry(int index) {
|
||||
result.hasIndex(index) and
|
||||
|
||||
@@ -57,4 +57,3 @@ private import implementations.CAtlFile
|
||||
private import implementations.CAtlFileMapping
|
||||
private import implementations.CAtlTemporaryFile
|
||||
private import implementations.CRegKey
|
||||
private import implementations.WinHttp
|
||||
|
||||
@@ -1,50 +0,0 @@
|
||||
private import cpp
|
||||
private import semmle.code.cpp.ir.dataflow.FlowSteps
|
||||
private import semmle.code.cpp.dataflow.new.DataFlow
|
||||
|
||||
/** The `WINHTTP_HEADER_NAME` class from `winhttp.h`. */
|
||||
class WinHttpHeaderName extends Class {
|
||||
WinHttpHeaderName() { this.hasGlobalName("_WINHTTP_HEADER_NAME") }
|
||||
}
|
||||
|
||||
/** The `WINHTTP_EXTENDED_HEADER` class from `winhttp.h`. */
|
||||
class WinHttpExtendedHeader extends Class {
|
||||
WinHttpExtendedHeader() { this.hasGlobalName("_WINHTTP_EXTENDED_HEADER") }
|
||||
}
|
||||
|
||||
private class WinHttpHeaderNameInheritingContent extends TaintInheritingContent,
|
||||
DataFlow::FieldContent
|
||||
{
|
||||
WinHttpHeaderNameInheritingContent() {
|
||||
this.getIndirectionIndex() = 2 and
|
||||
(
|
||||
this.getAField().getDeclaringType() instanceof WinHttpHeaderName
|
||||
or
|
||||
// The extended header looks like:
|
||||
// struct WINHTTP_EXTENDED_HEADER {
|
||||
// union { [...] };
|
||||
// union { [...] };
|
||||
// };
|
||||
// So the first declaring type is the anonymous unions, and the declaring
|
||||
// type of those anonymous unions is the `WINHTTP_EXTENDED_HEADER` struct.
|
||||
this.getAField().getDeclaringType().getDeclaringType() instanceof WinHttpExtendedHeader
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/** The `URL_COMPONENTS` class from `winhttp.h`. */
|
||||
class WinHttpUrlComponents extends Class {
|
||||
WinHttpUrlComponents() { this.hasGlobalName("_WINHTTP_URL_COMPONENTS") }
|
||||
}
|
||||
|
||||
private class WinHttpUrlComponentsInheritingContent extends TaintInheritingContent,
|
||||
DataFlow::FieldContent
|
||||
{
|
||||
WinHttpUrlComponentsInheritingContent() {
|
||||
exists(Field f | f = this.getField() and f.getDeclaringType() instanceof WinHttpUrlComponents |
|
||||
if f.getType().getUnspecifiedType() instanceof PointerType
|
||||
then this.getIndirectionIndex() = 2
|
||||
else this.getIndirectionIndex() = 1
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -404,7 +404,7 @@ predicate cmpWithLinearBound(
|
||||
* For example, if `t` is a signed 32-bit type then holds if `lb` is
|
||||
* `-2^31` and `ub` is `2^31 - 1`.
|
||||
*/
|
||||
private predicate typeBounds0(ArithmeticType t, float lb, float ub) {
|
||||
private predicate typeBounds(ArithmeticType t, float lb, float ub) {
|
||||
exists(IntegralType integralType, float limit |
|
||||
integralType = t and limit = 2.pow(8 * integralType.getSize())
|
||||
|
|
||||
@@ -423,42 +423,6 @@ private predicate typeBounds0(ArithmeticType t, float lb, float ub) {
|
||||
t instanceof FloatingPointType and lb = -(1.0 / 0.0) and ub = 1.0 / 0.0
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the underlying type for an enumeration `e`.
|
||||
*
|
||||
* If the enumeration does not have an explicit type we approximate it using
|
||||
* the following rules:
|
||||
* - The result type is always `signed`, and
|
||||
* - if the largest value fits in an `int` the result is `int`. Otherwise, the
|
||||
* result is `long`.
|
||||
*/
|
||||
private IntegralType getUnderlyingTypeForEnum(Enum e) {
|
||||
result = e.getExplicitUnderlyingType()
|
||||
or
|
||||
not e.hasExplicitUnderlyingType() and
|
||||
result.isSigned() and
|
||||
exists(IntType intType |
|
||||
if max(e.getAnEnumConstant().getValue().toFloat()) >= 2.pow(8 * intType.getSize() - 1)
|
||||
then result instanceof LongType
|
||||
else result = intType
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if `lb` and `ub` are the lower and upper bounds of the unspecified
|
||||
* type `t`.
|
||||
*
|
||||
* For example, if `t` is a signed 32-bit type then holds if `lb` is
|
||||
* `-2^31` and `ub` is `2^31 - 1`.
|
||||
*
|
||||
* Unlike `typeBounds0`, this predicate also handles `Enum` types.
|
||||
*/
|
||||
private predicate typeBounds(Type t, float lb, float ub) {
|
||||
typeBounds0(t, lb, ub)
|
||||
or
|
||||
typeBounds0(getUnderlyingTypeForEnum(t), lb, ub)
|
||||
}
|
||||
|
||||
private Type stripReference(Type t) {
|
||||
if t instanceof ReferenceType then result = t.(ReferenceType).getBaseType() else result = t
|
||||
}
|
||||
|
||||
@@ -512,8 +512,8 @@ private module BoundsEstimate {
|
||||
*/
|
||||
float getBoundsLimit() {
|
||||
// This limit is arbitrary, but low enough that it prevents timeouts on
|
||||
// specific observed customer databases (and in the tests).
|
||||
result = 2.0.pow(29)
|
||||
// specific observed customer databases (and the in the tests).
|
||||
result = 2.0.pow(40)
|
||||
}
|
||||
|
||||
/** Gets the maximum number of bounds possible for `t` when widening is used. */
|
||||
@@ -552,47 +552,34 @@ private module BoundsEstimate {
|
||||
private float nrOfBoundsPhiGuard(RangeSsaDefinition def, StackVariable v) {
|
||||
// If we have
|
||||
//
|
||||
// if (x < c) { e1 } else { e2 }
|
||||
// e3
|
||||
//
|
||||
// then `{ e1 }` and `{ e2 }` are both guard phi nodes guarded by `x < c`.
|
||||
// The range analysis propagates bounds on `x` into both branches, filtered
|
||||
// by the condition. In this case all lower bounds flow to `{ e1 }` and only
|
||||
// lower bounds that are smaller than `c` flow to `{ e2 }`.
|
||||
//
|
||||
// The largest number of bounds possible for `e3` is the number of bounds on `x` plus
|
||||
// one. This happens when all bounds flow from `x` to `e1` to `e3` and the
|
||||
// bound `c` can flow to `e2` to `e3`.
|
||||
//
|
||||
// We want to optimize our bounds estimate for `e3`, as that is the estimate
|
||||
// that can continue propagating forward. We don't know how the existing
|
||||
// bounds will be split between the different branches. That depends on
|
||||
// whether the range analysis is tracking lower bounds or upper bounds, and
|
||||
// on the meaning of the condition.
|
||||
//
|
||||
// As a heuristic we divide the number of bounds on `x` by 2 to "average"
|
||||
// the effect of the condition and add 1 to account for the bound from the
|
||||
// condition itself. This will approximate estimates inside the branches,
|
||||
// but will give a good estimate after the branches are merged.
|
||||
//
|
||||
// This also handles cases such as this one
|
||||
//
|
||||
// if (x < c) { e1 }
|
||||
// e3
|
||||
// e2
|
||||
//
|
||||
// where `e3` is both a guard phi node (guarded by `x < c`) and a normal
|
||||
// phi node (control is merged after the `if` statement). Here half of the
|
||||
// bounds flow into the branch and then to `e3` as a normal phi node and the
|
||||
// "other" half flow from the condition to `e3` as a guard phi node.
|
||||
exists(float varBounds |
|
||||
// If there's different `access`es, then they refer to the same
|
||||
// variable with the same lower bounds. Hence adding these guards makes no
|
||||
// sense (the implementation will take the union, but they'll be removed by
|
||||
// deduplication). Hence we use `max` as an approximation.
|
||||
varBounds =
|
||||
max(VariableAccess access | isGuardPhiWithBound(def, v, access) | nrOfBoundsExpr(access)) and
|
||||
result = (varBounds + 1) / 2
|
||||
)
|
||||
// then `e2` is both a guard phi node (guarded by `x < c`) and a normal
|
||||
// phi node (control is merged after the `if` statement).
|
||||
//
|
||||
// Assume `x` has `n` bounds. Then `n` bounds are propagated to the guard
|
||||
// phi node `{ e1 }` and, since `{ e1 }` is input to `e2` as a normal phi
|
||||
// node, `n` bounds are propagated to `e2`. If we also propagate the `n`
|
||||
// bounds to `e2` as a guard phi node, then we square the number of
|
||||
// bounds.
|
||||
//
|
||||
// However in practice `x < c` is going to cut down the number of bounds:
|
||||
// The tracked bounds can't flow to both branches as that would require
|
||||
// them to simultaneously be greater and smaller than `c`. To approximate
|
||||
// this better, the contribution from a guard phi node that is also a
|
||||
// normal phi node is 1.
|
||||
exists(def.getAPhiInput(v)) and
|
||||
isGuardPhiWithBound(def, v, _) and
|
||||
result = 1
|
||||
or
|
||||
not exists(def.getAPhiInput(v)) and
|
||||
// If there's different `access`es, then they refer to the same variable
|
||||
// with the same lower bounds. Hence adding these guards make no sense (the
|
||||
// implementation will take the union, but they'll be removed by
|
||||
// deduplication). Hence we use `max` as an approximation.
|
||||
result =
|
||||
max(VariableAccess access | isGuardPhiWithBound(def, v, access) | nrOfBoundsExpr(access))
|
||||
or
|
||||
def.isPhiNode(v) and
|
||||
not isGuardPhiWithBound(def, v, _) and
|
||||
@@ -2193,16 +2180,6 @@ module SimpleRangeAnalysisInternal {
|
||||
|
||||
/** Gets the estimate of the number of bounds for `e`. */
|
||||
float estimateNrOfBounds(Expr e) { result = BoundsEstimate::nrOfBoundsExpr(e) }
|
||||
|
||||
/** Counts the numbers of lower bounds that are computed internally for `e`. */
|
||||
float countNrOfLowerBounds(Expr e) {
|
||||
result = strictcount(float lb | lb = getLowerBoundsImpl(e) | lb)
|
||||
}
|
||||
|
||||
/** Counts the numbers of upper bounds that are computed internally for `e`. */
|
||||
float countNrOfUpperBounds(Expr e) {
|
||||
result = strictcount(float ub | ub = getUpperBoundsImpl(e) | ub)
|
||||
}
|
||||
}
|
||||
|
||||
/** Provides predicates for debugging the simple range analysis library. */
|
||||
@@ -2231,7 +2208,7 @@ private module Debug {
|
||||
*/
|
||||
predicate countGetLowerBoundsImpl(Expr e, int n) {
|
||||
e = getRelevantLocatable() and
|
||||
n = SimpleRangeAnalysisInternal::countNrOfLowerBounds(e)
|
||||
n = strictcount(float lb | lb = getLowerBoundsImpl(e) | lb)
|
||||
}
|
||||
|
||||
float debugNrOfBounds(Expr e) {
|
||||
|
||||
@@ -236,34 +236,6 @@ extractor_version(
|
||||
string frontend_version: string ref
|
||||
)
|
||||
|
||||
/**
|
||||
* Gives the TRAP filename that `trap` is associated with.
|
||||
* For debugging only.
|
||||
*/
|
||||
trap_filename(
|
||||
int trap: @trap,
|
||||
string filename: string ref
|
||||
);
|
||||
|
||||
/**
|
||||
* In `build-mode: none` overlay mode, indicates that `source_file`
|
||||
* (`/path/to/foo.c`) uses the TRAP file `trap_file`; i.e. it is the
|
||||
* TRAP file corresponding to `foo.c`, something it transitively
|
||||
* includes, or a template instantiation it transitively uses.
|
||||
*/
|
||||
source_file_uses_trap(
|
||||
string source_file: string ref,
|
||||
int trap_file: @trap ref
|
||||
);
|
||||
|
||||
/**
|
||||
* Holds if there is a definition of `element` in TRAP file `trap_file`.
|
||||
*/
|
||||
in_trap(
|
||||
int element: @element ref,
|
||||
int trap_file: @trap ref
|
||||
);
|
||||
|
||||
pch_uses(
|
||||
int pch: @pch ref,
|
||||
int compilation: @compilation ref,
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,2 +0,0 @@
|
||||
description: Add trap_filename, source_file_uses_trap and in_trap relations
|
||||
compatibility: full
|
||||
@@ -1,11 +1,3 @@
|
||||
## 1.5.12
|
||||
|
||||
No user-facing changes.
|
||||
|
||||
## 1.5.11
|
||||
|
||||
No user-facing changes.
|
||||
|
||||
## 1.5.10
|
||||
|
||||
No user-facing changes.
|
||||
|
||||
@@ -308,37 +308,3 @@ private module PossibleYearArithmeticOperationCheckConfig implements DataFlow::C
|
||||
|
||||
module PossibleYearArithmeticOperationCheckFlow =
|
||||
TaintTracking::Global<PossibleYearArithmeticOperationCheckConfig>;
|
||||
|
||||
/**
|
||||
* A time conversion function where either
|
||||
* 1) an incorrect leap year date would result in an error that can be checked from the return value or
|
||||
* 2) an incorrect leap year date is auto corrected (no checks required)
|
||||
*/
|
||||
class TimeConversionFunction extends Function {
|
||||
boolean autoLeapYearCorrecting;
|
||||
|
||||
TimeConversionFunction() {
|
||||
autoLeapYearCorrecting = false and
|
||||
(
|
||||
this.getName() =
|
||||
[
|
||||
"FileTimeToSystemTime", "SystemTimeToFileTime", "SystemTimeToTzSpecificLocalTime",
|
||||
"SystemTimeToTzSpecificLocalTimeEx", "TzSpecificLocalTimeToSystemTime",
|
||||
"TzSpecificLocalTimeToSystemTimeEx", "RtlLocalTimeToSystemTime",
|
||||
"RtlTimeToSecondsSince1970", "_mkgmtime", "SetSystemTime", "VarUdateFromDate", "from_tm"
|
||||
]
|
||||
or
|
||||
// Matches all forms of GetDateFormat, e.g. GetDateFormatA/W/Ex
|
||||
this.getName().matches("GetDateFormat%")
|
||||
)
|
||||
or
|
||||
autoLeapYearCorrecting = true and
|
||||
this.getName() =
|
||||
["mktime", "_mktime32", "_mktime64", "SystemTimeToVariantTime", "VariantTimeToSystemTime"]
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if the function is expected to auto convert a bad leap year date.
|
||||
*/
|
||||
predicate isAutoLeapYearCorrecting() { autoLeapYearCorrecting = true }
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/**
|
||||
* @name Year field changed using an arithmetic operation without checking for leap year
|
||||
* @description A field that represents a year is being modified by an arithmetic operation, but no proper check for leap years can be detected afterwards.
|
||||
* @kind path-problem
|
||||
* @kind problem
|
||||
* @problem.severity warning
|
||||
* @id cpp/leap-year/unchecked-after-arithmetic-year-modification
|
||||
* @precision medium
|
||||
@@ -11,844 +11,49 @@
|
||||
|
||||
import cpp
|
||||
import LeapYear
|
||||
import semmle.code.cpp.controlflow.IRGuards
|
||||
|
||||
/**
|
||||
* Functions whose operations should never be considered a
|
||||
* source or sink of a dangerous leap year operation.
|
||||
* The general concept is to add conversion functions
|
||||
* that convert one time type to another. Often
|
||||
* other ignorable operation heuristics will filter these,
|
||||
* but some cases, the simplest approach is to simply filter
|
||||
* the function entirely.
|
||||
* Note that flow through these functions should still be allowed
|
||||
* we just cannot start or end flow from an operation to a
|
||||
* year assignment in one of these functions.
|
||||
*/
|
||||
class IgnorableFunction extends Function {
|
||||
IgnorableFunction() {
|
||||
// arithmetic in known time conversion functions may look like dangerous operations
|
||||
// we assume all known time conversion functions are safe.
|
||||
this instanceof TimeConversionFunction
|
||||
or
|
||||
// Helper utility in postgres with string time conversions
|
||||
this.getName() = "DecodeISO8601Interval"
|
||||
or
|
||||
// helper utility for date conversions in qtbase
|
||||
this.getName() = "adjacentDay"
|
||||
or
|
||||
// Windows API function that does timezone conversions
|
||||
this.getName().matches("%SystemTimeToTzSpecificLocalTime%")
|
||||
or
|
||||
// Windows APIs that do time conversions
|
||||
this.getName().matches("%localtime%\\_s%")
|
||||
or
|
||||
// Windows APIs that do time conversions
|
||||
this.getName().matches("%SpecificLocalTimeToSystemTime%")
|
||||
or
|
||||
// postgres function for diffing timestamps, date for leap year
|
||||
// is not applicable.
|
||||
this.getName().toLowerCase().matches("%timestamp%age%")
|
||||
or
|
||||
// Reading byte streams often involves operations of some base, but that's
|
||||
// not a real source of leap year issues.
|
||||
this.getName().toLowerCase().matches("%read%bytes%")
|
||||
or
|
||||
// A postgres function for local time conversions
|
||||
// conversion operations (from one time structure to another) are generally ignorable
|
||||
this.getName() = "localsub"
|
||||
or
|
||||
// Indication of a calendar not applicable to
|
||||
// gregorian leap year, e.g., Hijri, Persian, Hebrew
|
||||
this.getName().toLowerCase().matches("%hijri%")
|
||||
or
|
||||
this.getFile().getBaseName().toLowerCase().matches("%hijri%")
|
||||
or
|
||||
this.getName().toLowerCase().matches("%persian%")
|
||||
or
|
||||
this.getFile().getBaseName().toLowerCase().matches("%persian%")
|
||||
or
|
||||
this.getName().toLowerCase().matches("%hebrew%")
|
||||
or
|
||||
this.getFile().getBaseName().toLowerCase().matches("%hebrew%")
|
||||
or
|
||||
// misc. from string/char converters heuristic
|
||||
this.getName()
|
||||
.toLowerCase()
|
||||
.matches(["%char%to%", "%string%to%", "%from%char%", "%from%string%"])
|
||||
or
|
||||
// boost's gregorian.cpp has year manipulations that are checked in complex ways.
|
||||
// ignore the entire file as a source or sink.
|
||||
this.getFile().getAbsolutePath().toLowerCase().matches("%boost%gregorian.cpp%")
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The set of expressions which are ignorable; either because they seem to not be part of a year mutation,
|
||||
* or because they seem to be a conversion pattern of mapping date scalars.
|
||||
*/
|
||||
abstract class IgnorableOperation extends Expr { }
|
||||
|
||||
class IgnorableExprRem extends IgnorableOperation instanceof RemExpr { }
|
||||
|
||||
/**
|
||||
* An operation with 10, 100, 1000, 10000 as an operand is often a sign of conversion
|
||||
* or atoi.
|
||||
*/
|
||||
class IgnorableExpr10MultipleComponent extends IgnorableOperation {
|
||||
IgnorableExpr10MultipleComponent() {
|
||||
this.(Operation).getAnOperand().getValue().toInt() in [10, 100, 1000, 10000]
|
||||
or
|
||||
exists(AssignOperation a | a.getRValue() = this |
|
||||
a.getRValue().getValue().toInt() in [10, 100, 1000, 10000]
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* An operation involving a sub expression with char literal `48`, ignore as a likely string conversion. For example: `X - '0'`
|
||||
*/
|
||||
class IgnorableExpr48Mapping extends IgnorableOperation {
|
||||
IgnorableExpr48Mapping() {
|
||||
this.(SubExpr).getRightOperand().getValue().toInt() = 48
|
||||
or
|
||||
exists(AssignSubExpr e | e.getRValue() = this | e.getRValue().getValue().toInt() = 48)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A binary or arithmetic operation whereby one of the components is textual or a string.
|
||||
*/
|
||||
class IgnorableCharLiteralArithmetic extends IgnorableOperation {
|
||||
IgnorableCharLiteralArithmetic() {
|
||||
this.(BinaryArithmeticOperation).getAnOperand() instanceof TextLiteral
|
||||
or
|
||||
this instanceof TextLiteral and
|
||||
any(AssignArithmeticOperation arith).getRValue() = this
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Constants often used in date conversions (from one date data type to another)
|
||||
* Numerous examples exist, like 1900 or 2000 that convert years from one
|
||||
* representation to another.
|
||||
* Also '0' is sometimes observed as an atoi style conversion.
|
||||
*/
|
||||
bindingset[c]
|
||||
predicate isLikelyConversionConstant(int c) {
|
||||
exists(int i | i = c.abs() |
|
||||
i =
|
||||
[
|
||||
146097, // days in 400-year Gregorian cycle
|
||||
36524, // days in 100-year Gregorian subcycle
|
||||
1461, // days in 4-year cycle (incl. 1 leap)
|
||||
32044, // Fliegel-van Flandern JDN epoch shift
|
||||
1721425, // JDN of 0001-01-01 (Gregorian)
|
||||
1721119, // alt epoch offset
|
||||
2400000, // MJD -> JDN conversion
|
||||
2400001, // alt MJD -> JDN conversion
|
||||
2141, // fixed-point month/day extraction
|
||||
65536, // observed in some conversions
|
||||
7834, // observed in some conversions
|
||||
256, // observed in some conversions
|
||||
292275056, // qdatetime.h Qt Core year range first year constant
|
||||
292278994, // qdatetime.h Qt Core year range last year constant
|
||||
1601, // Windows FILETIME epoch start year
|
||||
1970, // Unix epoch start year
|
||||
70, // Unix epoch start year short form
|
||||
1899, // Observed in uses with 1900 to address off by one scenarios
|
||||
1900, // Used when converting a 2 digit year
|
||||
2000, // Used when converting a 2 digit year
|
||||
1400, // Hijri base year, used when converting a 2 digit year
|
||||
1980, // FAT filesystem epoch start year
|
||||
227013, // constant observed for Hirji year conversion, and Hirji years are not applicable for gregorian leap year
|
||||
10631, // constant observed for Hirji year conversion, and Hirji years are not applicable for gregorian leap year,
|
||||
80, // 1980/01/01 is the start of the epoch on DOS
|
||||
0
|
||||
]
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* An `isLikelyConversionConstant` constant indicates conversion that is ignorable, e.g.,
|
||||
* julian to gregorian conversion or conversions from linux time structs
|
||||
* that start at 1900, etc.
|
||||
*/
|
||||
class IgnorableConstantArithmetic extends IgnorableOperation {
|
||||
IgnorableConstantArithmetic() {
|
||||
exists(int i | isLikelyConversionConstant(i) |
|
||||
this.(Operation).getAnOperand().getValue().toInt() = i
|
||||
or
|
||||
exists(AssignArithmeticOperation a | this = a.getRValue() |
|
||||
a.getRValue().getValue().toInt() = i
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
// If a unary minus assume it is some sort of conversion
|
||||
class IgnorableUnaryMinus extends IgnorableOperation {
|
||||
IgnorableUnaryMinus() {
|
||||
this instanceof UnaryMinusExpr
|
||||
or
|
||||
this.(Operation).getAnOperand() instanceof UnaryMinusExpr
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* An argument to a function is ignorable if the function that is called is an ignored function
|
||||
*/
|
||||
class OperationAsArgToIgnorableFunction extends IgnorableOperation {
|
||||
OperationAsArgToIgnorableFunction() {
|
||||
exists(Call c |
|
||||
c.getAnArgument().getAChild*() = this and
|
||||
c.getTarget() instanceof IgnorableFunction
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A binary operation on two literals means the result is constant/known
|
||||
* and the operation is basically ignorable (it's not a real operation but
|
||||
* probably one visual simplicity what it means).
|
||||
*/
|
||||
class ConstantBinaryArithmeticOperation extends IgnorableOperation, BinaryArithmeticOperation {
|
||||
ConstantBinaryArithmeticOperation() {
|
||||
this.getLeftOperand() instanceof Literal and
|
||||
this.getRightOperand() instanceof Literal
|
||||
}
|
||||
}
|
||||
|
||||
class IgnorableBinaryBitwiseOperation extends IgnorableOperation instanceof BinaryBitwiseOperation {
|
||||
}
|
||||
|
||||
class IgnorableUnaryBitwiseOperation extends IgnorableOperation instanceof UnaryBitwiseOperation { }
|
||||
|
||||
class IgnorableAssignmentBitwiseOperation extends IgnorableOperation instanceof AssignBitwiseOperation
|
||||
{ }
|
||||
|
||||
/**
|
||||
* An arithmetic operation where one of the operands is a pointer or char type, ignore it
|
||||
*/
|
||||
class IgnorablePointerOrCharArithmetic extends IgnorableOperation {
|
||||
IgnorablePointerOrCharArithmetic() {
|
||||
this instanceof BinaryArithmeticOperation and
|
||||
exists(Expr op | op = this.(BinaryArithmeticOperation).getAnOperand() |
|
||||
op.getUnspecifiedType() instanceof PointerType
|
||||
or
|
||||
op.getUnspecifiedType() instanceof CharType
|
||||
or
|
||||
// Operations on calls to functions that accept char or char*
|
||||
op.(Call).getAnArgument().getUnspecifiedType().stripType() instanceof CharType
|
||||
or
|
||||
// Operations on calls to functions named like "strlen", "wcslen", etc
|
||||
// NOTE: workaround for cases where the wchar_t type is not a char, but an unsigned short
|
||||
// unclear if there is a best way to filter cases like these out based on type info.
|
||||
op.(Call).getTarget().getName().matches("%len%")
|
||||
)
|
||||
or
|
||||
exists(AssignArithmeticOperation a | a.getRValue() = this |
|
||||
exists(Expr op | op = a.getAnOperand() |
|
||||
op.getUnspecifiedType() instanceof PointerType
|
||||
or
|
||||
op.getUnspecifiedType() instanceof CharType
|
||||
or
|
||||
// Operations on calls to functions that accept char or char*
|
||||
op.(Call).getAnArgument().getUnspecifiedType().stripType() instanceof CharType
|
||||
)
|
||||
or
|
||||
// Operations on calls to functions named like "strlen", "wcslen", etc
|
||||
// for example `strlen(foo) + bar`
|
||||
this.(BinaryArithmeticOperation).getAnOperand().(Call).getTarget().getName().matches("%len%")
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds for an expression that is an add or similar operation that could flow to a Year field.
|
||||
*/
|
||||
predicate isOperationSourceCandidate(Expr e) {
|
||||
not e instanceof IgnorableOperation and
|
||||
exists(Function f |
|
||||
f = e.getEnclosingFunction() and
|
||||
not f instanceof IgnorableFunction
|
||||
) and
|
||||
(
|
||||
e instanceof SubExpr
|
||||
or
|
||||
e instanceof AddExpr
|
||||
or
|
||||
e instanceof CrementOperation
|
||||
or
|
||||
e instanceof AssignSubExpr
|
||||
or
|
||||
e instanceof AssignAddExpr
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* A data flow that tracks an ignorable operation (such as a bitwise operation) to an operation source, so we may disqualify it.
|
||||
*/
|
||||
module IgnorableOperationToOperationSourceCandidateConfig implements DataFlow::ConfigSig {
|
||||
predicate isSource(DataFlow::Node n) { n.asExpr() instanceof IgnorableOperation }
|
||||
|
||||
predicate isSink(DataFlow::Node n) { isOperationSourceCandidate(n.asExpr()) }
|
||||
|
||||
// looking for sources and sinks in the same function
|
||||
DataFlow::FlowFeature getAFeature() {
|
||||
result instanceof DataFlow::FeatureEqualSourceSinkCallContext
|
||||
}
|
||||
}
|
||||
|
||||
module IgnorableOperationToOperationSourceCandidateFlow =
|
||||
TaintTracking::Global<IgnorableOperationToOperationSourceCandidateConfig>;
|
||||
|
||||
/**
|
||||
* The set of all expressions which is a candidate expression and also does not flow from to to some ignorable expression (eg. bitwise op)
|
||||
* ```
|
||||
* a = something <<< 2;
|
||||
* myDate.year = a + 1; // invalid
|
||||
* ...
|
||||
* a = someDate.year + 1;
|
||||
* myDate.year = a; // valid
|
||||
* ```
|
||||
*/
|
||||
class OperationSource extends Expr {
|
||||
OperationSource() {
|
||||
isOperationSourceCandidate(this) and
|
||||
// If the candidate came from an ignorable operation, ignore the candidate
|
||||
// NOTE: we cannot easily flow the candidate to an ignorable operation as that can
|
||||
// be tricky in practice, e.g., a mod operation on a year would be part of a leap year check
|
||||
// but a mod operation ending in a year is more indicative of something to ignore (a conversion)
|
||||
not exists(IgnorableOperationToOperationSourceCandidateFlow::PathNode sink |
|
||||
sink.getNode().asExpr() = this and
|
||||
sink.isSink()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
class YearFieldAssignmentNode extends DataFlow::Node {
|
||||
YearFieldAccess access;
|
||||
|
||||
YearFieldAssignmentNode() {
|
||||
exists(Function f |
|
||||
f = this.getEnclosingCallable().getUnderlyingCallable() and not f instanceof IgnorableFunction
|
||||
) and
|
||||
(
|
||||
this.asDefinition().(Assignment).getLValue() = access
|
||||
or
|
||||
this.asDefinition().(CrementOperation).getOperand() = access
|
||||
or
|
||||
exists(Call c | c.getAnArgument() = access and this.asDefiningArgument() = access)
|
||||
or
|
||||
exists(Call c, AddressOfExpr aoe |
|
||||
c.getAnArgument() = aoe and
|
||||
aoe.getOperand() = access and
|
||||
this.asDefiningArgument() = aoe
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
YearFieldAccess getYearFieldAccess() { result = access }
|
||||
}
|
||||
|
||||
/**
|
||||
* A DataFlow configuration for identifying flows from an identified source
|
||||
* to the Year field of a date object.
|
||||
*/
|
||||
module OperationToYearAssignmentConfig implements DataFlow::ConfigSig {
|
||||
predicate isSource(DataFlow::Node n) { n.asExpr() instanceof OperationSource }
|
||||
|
||||
predicate isSink(DataFlow::Node n) {
|
||||
n instanceof YearFieldAssignmentNode and
|
||||
not isYearModifiedWithCheck(n) and
|
||||
not isControlledByMonthEqualityCheckNonFebruary(n.asExpr())
|
||||
}
|
||||
|
||||
predicate isBarrier(DataFlow::Node n) {
|
||||
exists(ArrayExpr arr | arr.getArrayOffset() = n.asExpr())
|
||||
or
|
||||
n.getType().getUnspecifiedType() instanceof PointerType
|
||||
or
|
||||
n.getType().getUnspecifiedType() instanceof CharType
|
||||
or
|
||||
// If a type resembles "string" ignore flow (likely string conversion, currently ignored)
|
||||
n.getType().getUnspecifiedType().stripType().getName().toLowerCase().matches("%string%")
|
||||
or
|
||||
n.asExpr() instanceof IgnorableOperation
|
||||
or
|
||||
// Flowing into variables that indicate likely non-gregorian years are barriers
|
||||
// e.g., names similar to hijri, persian, lunar, chinese, hebrew, etc.
|
||||
exists(Variable v |
|
||||
v.getName()
|
||||
.toLowerCase()
|
||||
.matches(["%hijri%", "%persian%", "%lunar%", "%chinese%", "%hebrew%"]) and
|
||||
v.getAnAccess() = [n.asIndirectExpr(), n.asExpr()]
|
||||
)
|
||||
or
|
||||
isLeapYearCheckSink(n)
|
||||
or
|
||||
// this is a bit of a hack to address cases where a year is normalized and checked, but the
|
||||
// normalized year is never itself assigned to the final year struct
|
||||
// isLeapYear(getCivilYear(year))
|
||||
// struct.year = year
|
||||
// This is assuming a user would have done this all on one line though.
|
||||
// setting a variable for the conversion and passing that separately would be more difficult to track
|
||||
// considering this approach good enough for current observed false positives
|
||||
exists(Expr arg |
|
||||
isLeapYearCheckCall(_, arg) and arg.getAChild*() = [n.asExpr(), n.asIndirectExpr()]
|
||||
)
|
||||
or
|
||||
// If as the flow progresses, the value holding a dangerous operation result
|
||||
// is apparently being passed by address to some function, it is more than likely
|
||||
// intended to be modified, and therefore, the definition is killed.
|
||||
exists(Call c | c.getAnArgument().(AddressOfExpr).getAnOperand() = n.asIndirectExpr())
|
||||
}
|
||||
|
||||
/** Block flow out of an operation source to get the "closest" operation to the sink */
|
||||
predicate isBarrierIn(DataFlow::Node n) { isSource(n) }
|
||||
|
||||
predicate isBarrierOut(DataFlow::Node n) { isSink(n) }
|
||||
}
|
||||
|
||||
module OperationToYearAssignmentFlow = TaintTracking::Global<OperationToYearAssignmentConfig>;
|
||||
|
||||
predicate isLeapYearCheckSink(DataFlow::Node sink) {
|
||||
exists(LeapYearGuardCondition lgc |
|
||||
lgc.checkedYearAccess() = [sink.asExpr(), sink.asIndirectExpr()]
|
||||
)
|
||||
or
|
||||
isLeapYearCheckCall(_, [sink.asExpr(), sink.asIndirectExpr()])
|
||||
}
|
||||
|
||||
predicate yearAssignmentToCheckCommonSteps(DataFlow::Node node1, DataFlow::Node node2) {
|
||||
// flow from a YearFieldAccess to the qualifier
|
||||
node2.asExpr() = node1.asExpr().(YearFieldAccess).getQualifier*()
|
||||
or
|
||||
// getting the 'access' can be tricky at definitions (assignments especially)
|
||||
// as dataflow uses asDefinition not asExpr.
|
||||
// the YearFieldAssignmentNode holds the access in these cases
|
||||
node1.(YearFieldAssignmentNode).getYearFieldAccess().getQualifier() = node2.asExpr()
|
||||
or
|
||||
// flow from a year access qualifier to a year field
|
||||
exists(YearFieldAccess yfa | node2.asExpr() = yfa and node1.asExpr() = yfa.getQualifier())
|
||||
or
|
||||
node1.(YearFieldAssignmentNode).getYearFieldAccess().getQualifier() = node2.asExpr()
|
||||
or
|
||||
// Pass through any intermediate struct
|
||||
exists(Assignment a |
|
||||
a.getRValue() = node1.asExpr() and
|
||||
node2.asExpr() = a.getLValue().(YearFieldAccess).getQualifier*()
|
||||
)
|
||||
or
|
||||
// in cases of t.year = x and the value of x is checked, but the year t.year isn't directly checked
|
||||
// flow from a year assignment node to an RHS if it is an assignment
|
||||
// e.g.,
|
||||
// t.year = x;
|
||||
// isLeapYear(x);
|
||||
// --> at this point there is no flow of t.year to a check, but only its raw value
|
||||
// To detect the flow of 'x' to the isLeapYear check,
|
||||
// flow from t.year to 'x' (at assignment, t.year = x, flow to the RHS to track use-use flow of x)
|
||||
exists(YearFieldAssignmentNode yfan |
|
||||
node1 = yfan and
|
||||
node2.asExpr() = yfan.asDefinition().(Assignment).getRValue()
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* A flow configuration from a Year field access to some Leap year check or guard
|
||||
*/
|
||||
module YearAssignmentToLeapYearCheckConfig implements DataFlow::ConfigSig {
|
||||
predicate isSource(DataFlow::Node source) { source instanceof YearFieldAssignmentNode }
|
||||
|
||||
predicate isSink(DataFlow::Node sink) { isLeapYearCheckSink(sink) }
|
||||
|
||||
predicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2) {
|
||||
yearAssignmentToCheckCommonSteps(node1, node2)
|
||||
}
|
||||
|
||||
/**
|
||||
* Enforcing the check must occur in the same call context as the source,
|
||||
* i.e., do not return from the source function and check in a caller.
|
||||
*/
|
||||
DataFlow::FlowFeature getAFeature() { result instanceof DataFlow::FeatureHasSourceCallContext }
|
||||
}
|
||||
|
||||
module YearAssignmentToLeapYearCheckFlow =
|
||||
TaintTracking::Global<YearAssignmentToLeapYearCheckConfig>;
|
||||
|
||||
/** Does there exist a flow from the given YearFieldAccess to a Leap Year check or guard? */
|
||||
predicate isYearModifiedWithCheck(YearFieldAssignmentNode n) {
|
||||
exists(YearAssignmentToLeapYearCheckFlow::PathNode src |
|
||||
src.isSource() and
|
||||
src.getNode() = n
|
||||
)
|
||||
or
|
||||
// If the time flows to a time conversion whose value/result is checked,
|
||||
// assume the leap year is being handled.
|
||||
exists(YearAssignmentToCheckedTimeConversionFlow::PathNode timeQualSrc |
|
||||
timeQualSrc.isSource() and
|
||||
timeQualSrc.getNode() = n
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* An expression which checks the value of a Month field `a->month == 1`.
|
||||
*/
|
||||
class MonthEqualityCheck extends EqualityOperation {
|
||||
MonthEqualityCheck() { this.getAnOperand() instanceof MonthFieldAccess }
|
||||
|
||||
Expr getExprCompared() {
|
||||
exists(Expr e |
|
||||
e = this.getAnOperand() and
|
||||
not e instanceof MonthFieldAccess and
|
||||
result = e
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
final class FinalMonthEqualityCheck = MonthEqualityCheck;
|
||||
|
||||
class MonthEqualityCheckGuard extends GuardCondition, FinalMonthEqualityCheck { }
|
||||
|
||||
/**
|
||||
* Verifies if the expression is guarded by a check on the Month property of a date struct, that is NOT February.
|
||||
*/
|
||||
bindingset[e]
|
||||
pragma[inline_late]
|
||||
predicate isControlledByMonthEqualityCheckNonFebruary(Expr e) {
|
||||
exists(MonthEqualityCheckGuard monthGuard, Expr compared |
|
||||
monthGuard.controls(e.getBasicBlock(), true) and
|
||||
compared = monthGuard.getExprCompared() and
|
||||
not compared.getValue().toInt() = 2
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Flow from a year field access to a time conversion function
|
||||
* that auto converts feb29 in non-leap year, or through a conversion function that doesn't
|
||||
* auto convert to a sanity check guard of the result for error conditions.
|
||||
*/
|
||||
module YearAssignmentToCheckedTimeConversionConfig implements DataFlow::StateConfigSig {
|
||||
// Flow state tracks if flow goes through a known time conversion function
|
||||
// see `TimeConversionFunction`.
|
||||
// A valid check with a time conversion function is either the case:
|
||||
// 1) the year flows into a time conversion function, and the time conversion function's result is checked or
|
||||
// 2) the year flows into a time conversion function that auto corrects for leap year, so no check is necessary.
|
||||
class FlowState = boolean;
|
||||
|
||||
predicate isSource(DataFlow::Node source, FlowState state) {
|
||||
source instanceof YearFieldAssignmentNode and
|
||||
state = false
|
||||
}
|
||||
|
||||
predicate isSink(DataFlow::Node sink, FlowState state) {
|
||||
// Case 1: Flow through a time conversion function that requires a check,
|
||||
// and we have arrived at a guard, implying the result was checked for possible error, including leap year error.
|
||||
// state = true indicates the flow went through a time conversion function
|
||||
state = true and
|
||||
(
|
||||
exists(IfStmt ifs | ifs.getCondition().getAChild*() = [sink.asExpr(), sink.asIndirectExpr()])
|
||||
or
|
||||
exists(ConditionalExpr ce |
|
||||
ce.getCondition().getAChild*() = [sink.asExpr(), sink.asIndirectExpr()]
|
||||
)
|
||||
or
|
||||
exists(Loop l | l.getCondition().getAChild*() = [sink.asExpr(), sink.asIndirectExpr()])
|
||||
)
|
||||
or
|
||||
// Case 2: Flow through a time conversion function that auto corrects for leap year, so no check is necessary.
|
||||
// state true or false, as flowing through a time conversion function is not necessary in this instance.
|
||||
state in [true, false] and
|
||||
exists(Call c, TimeConversionFunction f |
|
||||
f.isAutoLeapYearCorrecting() and
|
||||
c.getTarget() = f and
|
||||
c.getAnArgument().getAChild*() = [sink.asExpr(), sink.asIndirectExpr()]
|
||||
)
|
||||
}
|
||||
|
||||
predicate isAdditionalFlowStep(
|
||||
DataFlow::Node node1, FlowState state1, DataFlow::Node node2, FlowState state2
|
||||
) {
|
||||
state1 in [true, false] and
|
||||
state2 = true and
|
||||
exists(Call c |
|
||||
c.getTarget() instanceof TimeConversionFunction and
|
||||
c.getAnArgument().getAChild*() = [node1.asExpr(), node1.asIndirectExpr()] and
|
||||
node2.asExpr() = c
|
||||
)
|
||||
}
|
||||
|
||||
predicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2) {
|
||||
yearAssignmentToCheckCommonSteps(node1, node2)
|
||||
}
|
||||
|
||||
DataFlow::FlowFeature getAFeature() { result instanceof DataFlow::FeatureHasSourceCallContext }
|
||||
}
|
||||
|
||||
module YearAssignmentToCheckedTimeConversionFlow =
|
||||
DataFlow::GlobalWithState<YearAssignmentToCheckedTimeConversionConfig>;
|
||||
|
||||
/**
|
||||
* Finds flow from a parameter of a function to a leap year check.
|
||||
* This is necessary to handle for scenarios like this:
|
||||
*
|
||||
* year = DANGEROUS_OP // source
|
||||
* isLeap = isLeapYear(year);
|
||||
* // logic based on isLeap
|
||||
* struct.year = year; // sink
|
||||
*
|
||||
* In this case, we may flow a dangerous op to a year assignment, failing
|
||||
* to barrier the flow through a leap year check, as the leap year check
|
||||
* is nested, and dataflow does not progress down into the check and out.
|
||||
* Instead, the point of this flow is to detect isLeapYear's argument
|
||||
* is checked for leap year, making the isLeapYear call a barrier for
|
||||
* the dangerous flow if we flow through the parameter identified to
|
||||
* be checked.
|
||||
*/
|
||||
module ParameterToLeapYearCheckConfig implements DataFlow::ConfigSig {
|
||||
predicate isSource(DataFlow::Node source) { exists(source.asParameter()) }
|
||||
|
||||
predicate isSink(DataFlow::Node sink) {
|
||||
exists(LeapYearGuardCondition lgc |
|
||||
lgc.checkedYearAccess() = [sink.asExpr(), sink.asIndirectExpr()]
|
||||
)
|
||||
}
|
||||
|
||||
predicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2) {
|
||||
// flow from a YearFieldAccess to the qualifier
|
||||
node2.asExpr() = node1.asExpr().(YearFieldAccess).getQualifier*()
|
||||
or
|
||||
// flow from a year access qualifier to a year field
|
||||
exists(YearFieldAccess yfa | node2.asExpr() = yfa and node1.asExpr() = yfa.getQualifier())
|
||||
}
|
||||
|
||||
/**
|
||||
* Enforcing the check must occur in the same call context as the source,
|
||||
* i.e., do not return from the source function and check in a caller.
|
||||
*/
|
||||
DataFlow::FlowFeature getAFeature() { result instanceof DataFlow::FeatureHasSourceCallContext }
|
||||
}
|
||||
|
||||
// NOTE: I do not believe taint flow is necessary here as we should
|
||||
// be flowing directyly from some parameter to a leap year check.
|
||||
module ParameterToLeapYearCheckFlow = DataFlow::Global<ParameterToLeapYearCheckConfig>;
|
||||
|
||||
predicate isLeapYearCheckCall(Call c, Expr arg) {
|
||||
exists(ParameterToLeapYearCheckFlow::PathNode src, Function f, int i |
|
||||
src.isSource() and
|
||||
f.getParameter(i) = src.getNode().asParameter() and
|
||||
c.getTarget() = f and
|
||||
c.getArgument(i) = arg
|
||||
)
|
||||
}
|
||||
|
||||
class LeapYearGuardCondition extends GuardCondition {
|
||||
Expr yearSinkDiv4;
|
||||
Expr yearSinkDiv100;
|
||||
Expr yearSinkDiv400;
|
||||
|
||||
LeapYearGuardCondition() {
|
||||
exists(
|
||||
LogicalAndExpr andExpr, LogicalOrExpr orExpr, GuardCondition div4Check,
|
||||
GuardCondition div100Check, GuardCondition div400Check, GuardValue gv
|
||||
|
|
||||
// canonical case:
|
||||
// form: `(year % 4 == 0) && (year % 100 != 0 || year % 400 == 0)`
|
||||
// `!((year % 4 == 0) && (year % 100 != 0 || year % 400 == 0))`
|
||||
// `!(year % 4) && (year % 100 || !(year % 400))`
|
||||
// Also accepting `((year & 3) == 0) && (year % 100 != 0 || year % 400 == 0)`
|
||||
// and `(year % 4 == 0) && (year % 100 > 0 || year % 400 == 0)`
|
||||
this = andExpr and
|
||||
andExpr.hasOperands(div4Check, orExpr) and
|
||||
orExpr.hasOperands(div100Check, div400Check) and
|
||||
(
|
||||
// year % 4 == 0
|
||||
exists(RemExpr e |
|
||||
div4Check.comparesEq(e, 0, true, gv) and
|
||||
e.getRightOperand().getValue().toInt() = 4 and
|
||||
yearSinkDiv4 = e.getLeftOperand()
|
||||
)
|
||||
or
|
||||
// year & 3 == 0
|
||||
exists(BitwiseAndExpr e |
|
||||
div4Check.comparesEq(e, 0, true, gv) and
|
||||
e.getRightOperand().getValue().toInt() = 3 and
|
||||
yearSinkDiv4 = e.getLeftOperand()
|
||||
)
|
||||
) and
|
||||
exists(RemExpr e |
|
||||
// year % 100 != 0 or year % 100 > 0
|
||||
(
|
||||
div100Check.comparesEq(e, 0, false, gv) or
|
||||
div100Check.comparesLt(e, 1, false, gv)
|
||||
) and
|
||||
e.getRightOperand().getValue().toInt() = 100 and
|
||||
yearSinkDiv100 = e.getLeftOperand()
|
||||
) and
|
||||
// year % 400 == 0
|
||||
exists(RemExpr e |
|
||||
div400Check.comparesEq(e, 0, true, gv) and
|
||||
e.getRightOperand().getValue().toInt() = 400 and
|
||||
yearSinkDiv400 = e.getLeftOperand()
|
||||
)
|
||||
or
|
||||
// Inverted logic case:
|
||||
// `year % 4 != 0 || (year % 100 == 0 && year % 400 != 0)`
|
||||
// or `year & 3 != 0 || (year % 100 == 0 && year % 400 != 0)`
|
||||
// also accepting `year % 4 > 0 || (year % 100 == 0 && year % 400 > 0)`
|
||||
this = orExpr and
|
||||
orExpr.hasOperands(div4Check, andExpr) and
|
||||
andExpr.hasOperands(div100Check, div400Check) and
|
||||
(
|
||||
// year % 4 != 0 or year % 4 > 0
|
||||
exists(RemExpr e |
|
||||
(
|
||||
div4Check.comparesEq(e, 0, false, gv)
|
||||
or
|
||||
div4Check.comparesLt(e, 1, false, gv)
|
||||
) and
|
||||
e.getRightOperand().getValue().toInt() = 4 and
|
||||
yearSinkDiv4 = e.getLeftOperand()
|
||||
)
|
||||
or
|
||||
// year & 3 != 0
|
||||
exists(BitwiseAndExpr e |
|
||||
div4Check.comparesEq(e, 0, false, gv) and
|
||||
e.getRightOperand().getValue().toInt() = 3 and
|
||||
yearSinkDiv4 = e.getLeftOperand()
|
||||
)
|
||||
) and
|
||||
// year % 100 == 0
|
||||
exists(RemExpr e |
|
||||
div100Check.comparesEq(e, 0, true, gv) and
|
||||
e.getRightOperand().getValue().toInt() = 100 and
|
||||
yearSinkDiv100 = e.getLeftOperand()
|
||||
) and
|
||||
// year % 400 != 0 or year % 400 > 0
|
||||
exists(RemExpr e |
|
||||
(
|
||||
div400Check.comparesEq(e, 0, false, gv)
|
||||
or
|
||||
div400Check.comparesLt(e, 1, false, gv)
|
||||
) and
|
||||
e.getRightOperand().getValue().toInt() = 400 and
|
||||
yearSinkDiv400 = e.getLeftOperand()
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
Expr getYearSinkDiv4() { result = yearSinkDiv4 }
|
||||
|
||||
Expr getYearSinkDiv100() { result = yearSinkDiv100 }
|
||||
|
||||
Expr getYearSinkDiv400() { result = yearSinkDiv400 }
|
||||
|
||||
/**
|
||||
* Gets the variable access that is used in all 3 components of the leap year check
|
||||
* e.g., see getYearSinkDiv4/100/400..
|
||||
* If a field access is used, the qualifier and the field access are both returned
|
||||
* in checked condition.
|
||||
* NOTE: if the year is not checked using the same access in all 3 components, no result is returned.
|
||||
* The typical case observed is a consistent variable access is used. If not, this may indicate a bug.
|
||||
* We could check more accurately with a dataflow analysis, but this is likely sufficient for now.
|
||||
*/
|
||||
VariableAccess checkedYearAccess() {
|
||||
exists(Variable var |
|
||||
(
|
||||
this.getYearSinkDiv4().getAChild*() = var.getAnAccess() and
|
||||
this.getYearSinkDiv100().getAChild*() = var.getAnAccess() and
|
||||
this.getYearSinkDiv400().getAChild*() = var.getAnAccess() and
|
||||
result = var.getAnAccess() and
|
||||
(
|
||||
result = this.getYearSinkDiv4().getAChild*() or
|
||||
result = this.getYearSinkDiv100().getAChild*() or
|
||||
result = this.getYearSinkDiv400().getAChild*()
|
||||
)
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A difficult case to detect is if a year modification is tied to a month or day modification
|
||||
* and the month or day is safe for leap year.
|
||||
* e.g.,
|
||||
* year++;
|
||||
* month = 1;
|
||||
* // alternative: day = 15;
|
||||
* ... values eventually used in the same time struct
|
||||
* If this is even more challenging if the struct the values end up in are not
|
||||
* local (set inter-procedurally).
|
||||
* This configuration looks for constants 1-31 flowing to a month or day assignment.
|
||||
* It is assumed a user of this flow will check if the month/day source and month/day sink
|
||||
* are in the same basic blocks as a year modification source and a year modification sink.
|
||||
* It is also assumed a user will check if the constant source is a value that is ignorable
|
||||
* e.g., if it is 2 and the sink is a month assignment, then it isn't ignorable or
|
||||
* if the value is < 27 and is a day assignment, it is likely ignorable
|
||||
*
|
||||
* Obviously this does not handle all conditions (e.g., the month set in another block).
|
||||
* It is meant to capture the most common cases of false positives.
|
||||
*/
|
||||
module CandidateConstantToDayOrMonthAssignmentConfig implements DataFlow::ConfigSig {
|
||||
predicate isSource(DataFlow::Node source) {
|
||||
source.asExpr().getValue().toInt() in [1 .. 31] and
|
||||
(
|
||||
exists(Assignment a | a.getRValue() = source.asExpr())
|
||||
or
|
||||
exists(Call c | c.getAnArgument() = source.asExpr())
|
||||
)
|
||||
}
|
||||
|
||||
predicate isSink(DataFlow::Node sink) {
|
||||
exists(Assignment a |
|
||||
(a.getLValue() instanceof MonthFieldAccess or a.getLValue() instanceof DayFieldAccess) and
|
||||
a.getRValue() = sink.asExpr()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
// NOTE: only data flow here (no taint tracking) as we want the exact
|
||||
// constant flowing to the month assignment
|
||||
module CandidateConstantToDayOrMonthAssignmentFlow =
|
||||
DataFlow::Global<CandidateConstantToDayOrMonthAssignmentConfig>;
|
||||
|
||||
/**
|
||||
* Holds if value the assignment `a` resolves to (`dayOrMonthValSrcExpr`) doesn't represent February,
|
||||
* and/or if it represents a day, is a 'safe' day (meaning the 27th or prior).
|
||||
*/
|
||||
bindingset[dayOrMonthValSrcExpr]
|
||||
predicate isSafeValueForAssignmentOfMonthOrDayValue(Assignment a, Expr dayOrMonthValSrcExpr) {
|
||||
a.getLValue() instanceof MonthFieldAccess and
|
||||
dayOrMonthValSrcExpr.getValue().toInt() != 2
|
||||
or
|
||||
a.getLValue() instanceof DayFieldAccess and
|
||||
dayOrMonthValSrcExpr.getValue().toInt() <= 27
|
||||
}
|
||||
|
||||
import OperationToYearAssignmentFlow::PathGraph
|
||||
|
||||
from OperationToYearAssignmentFlow::PathNode src, OperationToYearAssignmentFlow::PathNode sink
|
||||
from Variable var, LeapYearFieldAccess yfa
|
||||
where
|
||||
OperationToYearAssignmentFlow::flowPath(src, sink) and
|
||||
// Check if a month is set in the same block as the year operation source
|
||||
// and the month value would indicate its set to any other month than february.
|
||||
// Finds if the source year node is in the same block as a source month block
|
||||
// and if the same for the sinks.
|
||||
not exists(DataFlow::Node dayOrMonthValSrc, DataFlow::Node dayOrMonthValSink, Assignment a |
|
||||
CandidateConstantToDayOrMonthAssignmentFlow::flow(dayOrMonthValSrc, dayOrMonthValSink) and
|
||||
a.getRValue() = dayOrMonthValSink.asExpr() and
|
||||
dayOrMonthValSink.getBasicBlock() = sink.getNode().getBasicBlock() and
|
||||
exists(IRBlock dayOrMonthValBB |
|
||||
dayOrMonthValBB = dayOrMonthValSrc.getBasicBlock() and
|
||||
// The source of the day is set in the same block as the source for the year
|
||||
// or the source for the day is set in the same block as the sink for the year
|
||||
dayOrMonthValBB in [
|
||||
src.getNode().getBasicBlock(),
|
||||
sink.getNode().getBasicBlock()
|
||||
]
|
||||
) and
|
||||
isSafeValueForAssignmentOfMonthOrDayValue(a, dayOrMonthValSrc.asExpr())
|
||||
exists(VariableAccess va |
|
||||
yfa.getQualifier() = va and
|
||||
var.getAnAccess() = va and
|
||||
// The year is modified with an arithmetic operation. Avoid values that are likely false positives
|
||||
yfa.isModifiedByArithmeticOperationNotForNormalization() and
|
||||
// Avoid false positives
|
||||
not (
|
||||
// If there is a local check for leap year after the modification
|
||||
exists(LeapYearFieldAccess yfacheck |
|
||||
yfacheck.getQualifier() = var.getAnAccess() and
|
||||
yfacheck.isUsedInCorrectLeapYearCheck() and
|
||||
yfacheck.getBasicBlock() = yfa.getBasicBlock().getASuccessor*()
|
||||
)
|
||||
or
|
||||
// If there is a data flow from the variable that was modified to a function that seems to check for leap year
|
||||
exists(VariableAccess source, ChecksForLeapYearFunctionCall fc |
|
||||
source = var.getAnAccess() and
|
||||
LeapYearCheckFlow::flow(DataFlow::exprNode(source), DataFlow::exprNode(fc.getAnArgument()))
|
||||
)
|
||||
or
|
||||
// If there is a data flow from the field that was modified to a function that seems to check for leap year
|
||||
exists(VariableAccess vacheck, YearFieldAccess yfacheck, ChecksForLeapYearFunctionCall fc |
|
||||
vacheck = var.getAnAccess() and
|
||||
yfacheck.getQualifier() = vacheck and
|
||||
LeapYearCheckFlow::flow(DataFlow::exprNode(yfacheck), DataFlow::exprNode(fc.getAnArgument()))
|
||||
)
|
||||
or
|
||||
// If there is a successor or predecessor that sets the month = 1
|
||||
exists(MonthFieldAccess mfa, AssignExpr ae |
|
||||
mfa.getQualifier() = var.getAnAccess() and
|
||||
mfa.isModified() and
|
||||
(
|
||||
mfa.getBasicBlock() = yfa.getBasicBlock().getASuccessor*() or
|
||||
yfa.getBasicBlock() = mfa.getBasicBlock().getASuccessor+()
|
||||
) and
|
||||
ae = mfa.getEnclosingElement() and
|
||||
ae.getAnOperand().getValue().toInt() = 1
|
||||
)
|
||||
)
|
||||
)
|
||||
select sink, src, sink,
|
||||
"Year field has been modified, but no appropriate check for LeapYear was found."
|
||||
select yfa,
|
||||
"Field $@ on variable $@ has been modified, but no appropriate check for LeapYear was found.",
|
||||
yfa.getTarget(), yfa.getTarget().toString(), var, var.toString()
|
||||
|
||||
@@ -44,9 +44,23 @@ class SafeTimeGatheringFunction extends Function {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This list of APIs should check for the return value to detect problems during the conversion.
|
||||
*/
|
||||
class TimeConversionFunction extends Function {
|
||||
TimeConversionFunction() {
|
||||
this.getQualifiedName() =
|
||||
[
|
||||
"FileTimeToSystemTime", "SystemTimeToFileTime", "SystemTimeToTzSpecificLocalTime",
|
||||
"SystemTimeToTzSpecificLocalTimeEx", "TzSpecificLocalTimeToSystemTime",
|
||||
"TzSpecificLocalTimeToSystemTimeEx", "RtlLocalTimeToSystemTime",
|
||||
"RtlTimeToSecondsSince1970", "_mkgmtime"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
from FunctionCall fcall, TimeConversionFunction trf, Variable var
|
||||
where
|
||||
not trf.isAutoLeapYearCorrecting() and
|
||||
fcall = trf.getACallToThisFunction() and
|
||||
fcall instanceof ExprInVoidContext and
|
||||
var.getUnderlyingType() instanceof UnpackedTimeType and
|
||||
|
||||
@@ -16,15 +16,17 @@
|
||||
import cpp
|
||||
import semmle.code.cpp.ir.IR
|
||||
import semmle.code.cpp.ir.dataflow.MustFlow
|
||||
import ReturnStackAllocatedMemory::PathGraph
|
||||
import PathGraph
|
||||
|
||||
/** Holds if `f` has a name that we interpret as evidence of intentionally returning the value of the stack pointer. */
|
||||
predicate intentionallyReturnsStackPointer(Function f) {
|
||||
f.getName().toLowerCase().matches(["%stack%", "%sp%"])
|
||||
}
|
||||
|
||||
module ReturnStackAllocatedMemoryConfig implements MustFlow::ConfigSig {
|
||||
predicate isSource(Instruction source) {
|
||||
class ReturnStackAllocatedMemoryConfig extends MustFlowConfiguration {
|
||||
ReturnStackAllocatedMemoryConfig() { this = "ReturnStackAllocatedMemoryConfig" }
|
||||
|
||||
override predicate isSource(Instruction source) {
|
||||
exists(Function func |
|
||||
// Rule out FPs caused by extraction errors.
|
||||
not func.hasErrors() and
|
||||
@@ -48,7 +50,7 @@ module ReturnStackAllocatedMemoryConfig implements MustFlow::ConfigSig {
|
||||
)
|
||||
}
|
||||
|
||||
predicate isSink(Operand sink) {
|
||||
override predicate isSink(Operand sink) {
|
||||
// Holds if `sink` is a node that represents the `StoreInstruction` that is subsequently used in
|
||||
// a `ReturnValueInstruction`.
|
||||
// We use the `StoreInstruction` instead of the instruction that defines the
|
||||
@@ -70,7 +72,7 @@ module ReturnStackAllocatedMemoryConfig implements MustFlow::ConfigSig {
|
||||
// int* px = id(&x);
|
||||
// }
|
||||
// ```
|
||||
predicate allowInterproceduralFlow() { none() }
|
||||
override predicate allowInterproceduralFlow() { none() }
|
||||
|
||||
/**
|
||||
* This configuration intentionally conflates addresses of fields and their object, and pointer offsets
|
||||
@@ -85,22 +87,20 @@ module ReturnStackAllocatedMemoryConfig implements MustFlow::ConfigSig {
|
||||
* }
|
||||
* ```
|
||||
*/
|
||||
predicate isAdditionalFlowStep(Operand node1, Instruction node2) {
|
||||
override predicate isAdditionalFlowStep(Operand node1, Instruction node2) {
|
||||
node2.(FieldAddressInstruction).getObjectAddressOperand() = node1
|
||||
or
|
||||
node2.(PointerOffsetInstruction).getLeftOperand() = node1
|
||||
}
|
||||
|
||||
predicate isBarrier(Instruction n) { n.getResultType() instanceof ErroneousType }
|
||||
override predicate isBarrier(Instruction n) { n.getResultType() instanceof ErroneousType }
|
||||
}
|
||||
|
||||
module ReturnStackAllocatedMemory = MustFlow::Global<ReturnStackAllocatedMemoryConfig>;
|
||||
|
||||
from
|
||||
ReturnStackAllocatedMemory::PathNode source, ReturnStackAllocatedMemory::PathNode sink,
|
||||
Instruction instr
|
||||
MustFlowPathNode source, MustFlowPathNode sink, Instruction instr,
|
||||
ReturnStackAllocatedMemoryConfig conf
|
||||
where
|
||||
ReturnStackAllocatedMemory::flowPath(pragma[only_bind_into](source), pragma[only_bind_into](sink)) and
|
||||
conf.hasFlowPath(pragma[only_bind_into](source), pragma[only_bind_into](sink)) and
|
||||
source.getInstruction() = instr
|
||||
select sink.getInstruction(), source, sink, "May return stack-allocated memory from $@.",
|
||||
instr.getAst(), instr.getAst().toString()
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
import cpp
|
||||
import semmle.code.cpp.ir.IR
|
||||
import semmle.code.cpp.ir.dataflow.MustFlow
|
||||
import UninitializedLocal::PathGraph
|
||||
import PathGraph
|
||||
|
||||
/**
|
||||
* Auxiliary predicate: Types that don't require initialization
|
||||
@@ -70,26 +70,25 @@ predicate isSinkImpl(Instruction sink, VariableAccess va) {
|
||||
)
|
||||
}
|
||||
|
||||
module UninitializedLocalConfig implements MustFlow::ConfigSig {
|
||||
predicate isSource(Instruction source) {
|
||||
class MustFlow extends MustFlowConfiguration {
|
||||
MustFlow() { this = "MustFlow" }
|
||||
|
||||
override predicate isSource(Instruction source) {
|
||||
source instanceof UninitializedInstruction and
|
||||
exists(Type t | t = source.getResultType() | not allocatedType(t))
|
||||
}
|
||||
|
||||
predicate isSink(Operand sink) { isSinkImpl(sink.getDef(), _) }
|
||||
override predicate isSink(Operand sink) { isSinkImpl(sink.getDef(), _) }
|
||||
|
||||
predicate allowInterproceduralFlow() { none() }
|
||||
override predicate allowInterproceduralFlow() { none() }
|
||||
|
||||
predicate isBarrier(Instruction instr) { instr instanceof ChiInstruction }
|
||||
override predicate isBarrier(Instruction instr) { instr instanceof ChiInstruction }
|
||||
}
|
||||
|
||||
module UninitializedLocal = MustFlow::Global<UninitializedLocalConfig>;
|
||||
|
||||
from
|
||||
VariableAccess va, LocalVariable v, UninitializedLocal::PathNode source,
|
||||
UninitializedLocal::PathNode sink
|
||||
VariableAccess va, LocalVariable v, MustFlow conf, MustFlowPathNode source, MustFlowPathNode sink
|
||||
where
|
||||
UninitializedLocal::flowPath(source, sink) and
|
||||
conf.hasFlowPath(source, sink) and
|
||||
isSinkImpl(sink.getInstruction(), va) and
|
||||
v = va.getTarget()
|
||||
select va, source, sink, "The variable $@ may not be initialized at this access.", v, v.getName()
|
||||
|
||||
@@ -17,16 +17,16 @@
|
||||
import cpp
|
||||
import semmle.code.cpp.ir.IR
|
||||
import semmle.code.cpp.ir.dataflow.MustFlow
|
||||
import UnsafeUseOfThis::PathGraph
|
||||
import PathGraph
|
||||
|
||||
module UnsafeUseOfThisConfig implements MustFlow::ConfigSig {
|
||||
predicate isSource(Instruction source) { isSource(source, _, _) }
|
||||
class UnsafeUseOfThisConfig extends MustFlowConfiguration {
|
||||
UnsafeUseOfThisConfig() { this = "UnsafeUseOfThisConfig" }
|
||||
|
||||
predicate isSink(Operand sink) { isSink(sink, _) }
|
||||
override predicate isSource(Instruction source) { isSource(source, _, _) }
|
||||
|
||||
override predicate isSink(Operand sink) { isSink(sink, _) }
|
||||
}
|
||||
|
||||
module UnsafeUseOfThis = MustFlow::Global<UnsafeUseOfThisConfig>;
|
||||
|
||||
/** Holds if `sink` is a `this` pointer used by the call instruction `call`. */
|
||||
predicate isSink(Operand sink, CallInstruction call) {
|
||||
exists(PureVirtualFunction func |
|
||||
@@ -66,17 +66,19 @@ predicate isSource(InitializeParameterInstruction source, string msg, Class c) {
|
||||
* - `msg` is a string describing whether `source` is from a constructor or destructor.
|
||||
*/
|
||||
predicate flows(
|
||||
UnsafeUseOfThis::PathNode source, string msg, Class sourceClass, UnsafeUseOfThis::PathNode sink,
|
||||
MustFlowPathNode source, string msg, Class sourceClass, MustFlowPathNode sink,
|
||||
CallInstruction call
|
||||
) {
|
||||
UnsafeUseOfThis::flowPath(source, sink) and
|
||||
isSource(source.getInstruction(), msg, sourceClass) and
|
||||
isSink(sink.getInstruction().getAUse(), call)
|
||||
exists(UnsafeUseOfThisConfig conf |
|
||||
conf.hasFlowPath(source, sink) and
|
||||
isSource(source.getInstruction(), msg, sourceClass) and
|
||||
isSink(sink.getInstruction().getAUse(), call)
|
||||
)
|
||||
}
|
||||
|
||||
from
|
||||
UnsafeUseOfThis::PathNode source, UnsafeUseOfThis::PathNode sink, CallInstruction call,
|
||||
string msg, Class sourceClass
|
||||
MustFlowPathNode source, MustFlowPathNode sink, CallInstruction call, string msg,
|
||||
Class sourceClass
|
||||
where
|
||||
flows(source, msg, sourceClass, sink, call) and
|
||||
// Only raise an alert if there is no override of the pure virtual function in any base class.
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
## 1.5.11
|
||||
|
||||
No user-facing changes.
|
||||
@@ -1,3 +0,0 @@
|
||||
## 1.5.12
|
||||
|
||||
No user-facing changes.
|
||||
@@ -1,2 +1,2 @@
|
||||
---
|
||||
lastReleaseVersion: 1.5.12
|
||||
lastReleaseVersion: 1.5.10
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
name: codeql/cpp-queries
|
||||
version: 1.5.13-dev
|
||||
version: 1.5.10
|
||||
groups:
|
||||
- cpp
|
||||
- queries
|
||||
|
||||
@@ -1,297 +0,0 @@
|
||||
using uint16_t = unsigned short;
|
||||
using int64_t = long long;
|
||||
using size_t = unsigned long;
|
||||
using uint8_t = unsigned char;
|
||||
using int32_t = int;
|
||||
using uint32_t = unsigned int;
|
||||
|
||||
namespace std
|
||||
{
|
||||
class string
|
||||
{
|
||||
public:
|
||||
string();
|
||||
string(const char *);
|
||||
~string();
|
||||
};
|
||||
|
||||
template <typename K, typename V>
|
||||
class map
|
||||
{
|
||||
public:
|
||||
map();
|
||||
~map();
|
||||
|
||||
V& operator[](const K& key);
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
class vector
|
||||
{
|
||||
public:
|
||||
vector();
|
||||
~vector();
|
||||
|
||||
T& operator[](size_t);
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
class unique_ptr {
|
||||
public:
|
||||
unique_ptr();
|
||||
~unique_ptr();
|
||||
|
||||
T* get();
|
||||
};
|
||||
}
|
||||
|
||||
namespace Azure
|
||||
{
|
||||
template <typename T>
|
||||
class Nullable
|
||||
{
|
||||
public:
|
||||
Nullable();
|
||||
Nullable(const T);
|
||||
Nullable(const Nullable &);
|
||||
~Nullable();
|
||||
Nullable (Nullable &&);
|
||||
Nullable & operator= (const Nullable &);
|
||||
bool HasValue() const;
|
||||
const T & Value () const;
|
||||
T& Value ();
|
||||
const T * operator-> () const;
|
||||
T * operator-> ();
|
||||
const T & operator* () const;
|
||||
T & operator* ();
|
||||
};
|
||||
|
||||
namespace Core
|
||||
{
|
||||
class Url
|
||||
{
|
||||
public:
|
||||
Url();
|
||||
Url(const std::string &);
|
||||
void AppendPath(const std::string &encodedPath);
|
||||
void AppendQueryParameter(const std::string &encodedKey,
|
||||
const std::string &encodedValue);
|
||||
|
||||
static std::string Url::Decode(const std::string &value);
|
||||
static std::string Url::Encode(const std::string &value,
|
||||
const std::string &doNotEncodeSymbols = "");
|
||||
|
||||
std::string Url::GetAbsoluteUrl() const;
|
||||
const std::string &GetHost() const;
|
||||
const std::string &GetPath() const;
|
||||
uint16_t GetPort() const;
|
||||
std::map<std::string, std::string> GetQueryParameters() const;
|
||||
std::string Url::GetRelativeUrl() const;
|
||||
const std::string &GetScheme() const;
|
||||
void RemoveQueryParameter(const std::string &encodedKey);
|
||||
void SetHost(const std::string &encodedHost);
|
||||
void SetPath(const std::string &encodedPath);
|
||||
void SetPort(uint16_t port);
|
||||
void SetQueryParameters(std::map<std::string, std::string> queryParameters);
|
||||
void SetScheme(const std::string &scheme);
|
||||
};
|
||||
|
||||
class Context
|
||||
{
|
||||
public:
|
||||
Context();
|
||||
};
|
||||
|
||||
namespace IO
|
||||
{
|
||||
class BodyStream
|
||||
{
|
||||
public:
|
||||
virtual ~BodyStream();
|
||||
virtual int64_t Length() const = 0;
|
||||
virtual void Rewind();
|
||||
size_t Read(uint8_t *buffer, size_t count, Azure::Core::Context const &context = Azure::Core::Context());
|
||||
size_t ReadToCount(uint8_t *buffer, size_t count, Azure::Core::Context const &context = Azure::Core::Context());
|
||||
std::vector<uint8_t> ReadToEnd(Azure::Core::Context const &context = Azure::Core::Context());
|
||||
};
|
||||
}
|
||||
|
||||
enum class HttpStatusCode {
|
||||
None = 0,
|
||||
Continue = 100,
|
||||
SwitchingProtocols = 101,
|
||||
Processing = 102,
|
||||
EarlyHints = 103,
|
||||
OK = 200,
|
||||
Created = 201,
|
||||
Accepted = 202,
|
||||
NonAuthoritativeInformation = 203,
|
||||
NoContent = 204,
|
||||
ResetContent = 205,
|
||||
PartialContent = 206,
|
||||
MultiStatus = 207,
|
||||
AlreadyReported = 208,
|
||||
IMUsed = 226,
|
||||
MultipleChoices = 300,
|
||||
MovedPermanently = 301,
|
||||
Found = 302,
|
||||
SeeOther = 303,
|
||||
NotModified = 304,
|
||||
UseProxy = 305,
|
||||
TemporaryRedirect = 307,
|
||||
PermanentRedirect = 308,
|
||||
BadRequest = 400,
|
||||
Unauthorized = 401,
|
||||
PaymentRequired = 402,
|
||||
Forbidden = 403,
|
||||
NotFound = 404,
|
||||
MethodNotAllowed = 405,
|
||||
NotAcceptable = 406,
|
||||
ProxyAuthenticationRequired = 407,
|
||||
RequestTimeout = 408,
|
||||
Conflict = 409,
|
||||
Gone = 410,
|
||||
LengthRequired = 411,
|
||||
PreconditionFailed = 412,
|
||||
PayloadTooLarge = 413,
|
||||
URITooLong = 414,
|
||||
UnsupportedMediaType = 415,
|
||||
RangeNotSatisfiable = 416,
|
||||
ExpectationFailed = 417,
|
||||
MisdirectedRequest = 421,
|
||||
UnprocessableEntity = 422,
|
||||
Locked = 423,
|
||||
FailedDependency = 424,
|
||||
TooEarly = 425,
|
||||
UpgradeRequired = 426,
|
||||
PreconditionRequired = 428,
|
||||
TooManyRequests = 429,
|
||||
RequestHeaderFieldsTooLarge = 431,
|
||||
UnavailableForLegalReasons = 451,
|
||||
InternalServerError = 500,
|
||||
NotImplemented = 501,
|
||||
BadGateway = 502,
|
||||
ServiceUnavailable = 503,
|
||||
GatewayTimeout = 504,
|
||||
HTTPVersionNotSupported = 505,
|
||||
VariantAlsoNegotiates = 506,
|
||||
InsufficientStorage = 507,
|
||||
LoopDetected = 508,
|
||||
NotExtended = 510,
|
||||
NetworkAuthenticationRequired = 511
|
||||
};
|
||||
|
||||
namespace Http
|
||||
{
|
||||
class HttpMethod
|
||||
{
|
||||
public:
|
||||
HttpMethod(std::string value);
|
||||
bool operator==(const HttpMethod &other) const;
|
||||
bool operator!=(const HttpMethod &other) const;
|
||||
const std::string &ToString() const;
|
||||
};
|
||||
|
||||
extern const HttpMethod Get;
|
||||
extern const HttpMethod Head;
|
||||
extern const HttpMethod Post;
|
||||
extern const HttpMethod Put;
|
||||
extern const HttpMethod Delete;
|
||||
extern const HttpMethod Patch;
|
||||
extern const HttpMethod Options;
|
||||
|
||||
class Request
|
||||
{
|
||||
public:
|
||||
explicit Request(HttpMethod httpMethod,
|
||||
Url url);
|
||||
explicit Request(HttpMethod httpMethod,
|
||||
Url url,
|
||||
bool shouldBufferResponse);
|
||||
explicit Request(HttpMethod httpMethod,
|
||||
Url url,
|
||||
IO::BodyStream *bodyStream);
|
||||
explicit Request(HttpMethod httpMethod,
|
||||
Url url,
|
||||
IO::BodyStream *bodyStream,
|
||||
bool shouldBufferResponse);
|
||||
std::map<std::string, std::string> GetHeaders () const;
|
||||
Azure::Nullable<std::string> GetHeader(std::string const &name);
|
||||
IO::BodyStream * GetBodyStream();
|
||||
Azure::Core::IO::BodyStream const* GetBodyStream () const;
|
||||
};
|
||||
|
||||
class RawResponse {
|
||||
public:
|
||||
RawResponse (int32_t majorVersion, int32_t minorVersion, HttpStatusCode statusCode, std::string const &reasonPhrase);
|
||||
RawResponse (RawResponse const &response);
|
||||
RawResponse (RawResponse &&response);
|
||||
~RawResponse ();
|
||||
void SetHeader (std::string const &name, std::string const &value);
|
||||
void SetBodyStream (std::unique_ptr< Azure::Core::IO::BodyStream > stream);
|
||||
void SetBody (std::vector< uint8_t > body);
|
||||
uint32_t GetMajorVersion () const;
|
||||
uint32_t GetMinorVersion () const;
|
||||
HttpStatusCode GetStatusCode () const;
|
||||
std::string const & GetReasonPhrase () const;
|
||||
std::map<std::string, std::string>& GetHeaders () const;
|
||||
std::unique_ptr<Azure::Core::IO::BodyStream> ExtractBodyStream ();
|
||||
std::vector<uint8_t> & GetBody ();
|
||||
std::vector<uint8_t> const& GetBody() const;
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void sink(char);
|
||||
void sink(std::string);
|
||||
void sink(std::vector<uint8_t>);
|
||||
void sink(Azure::Nullable<std::string>);
|
||||
|
||||
void test_BodyStream() {
|
||||
Azure::Core::Http::Request request(Azure::Core::Http::Get, Azure::Core::Url("http://example.com"));
|
||||
Azure::Core::IO::BodyStream * resp = request.GetBodyStream();
|
||||
|
||||
{
|
||||
unsigned char buffer[1024];
|
||||
resp->Read(buffer, sizeof(buffer));
|
||||
sink(*buffer); // $ ir
|
||||
}
|
||||
{
|
||||
unsigned char buffer[1024];
|
||||
resp->ReadToCount(buffer, sizeof(buffer));
|
||||
sink(*buffer); // $ ir
|
||||
}
|
||||
{
|
||||
std::vector<unsigned char> vec = resp->ReadToEnd();
|
||||
sink(vec); // $ ir
|
||||
}
|
||||
}
|
||||
|
||||
void test_RawResponse(Azure::Core::Http::RawResponse& resp) {
|
||||
{
|
||||
std::map<std::string, std::string> body = resp.GetHeaders();
|
||||
sink(body["Content-Type"]); // $ ir
|
||||
}
|
||||
{
|
||||
std::vector<uint8_t> body = resp.GetBody();
|
||||
sink(body); // $ ir
|
||||
}
|
||||
{
|
||||
std::unique_ptr<Azure::Core::IO::BodyStream> bodyStream = resp.ExtractBodyStream();
|
||||
sink(bodyStream.get()->ReadToEnd()); // $ ir
|
||||
}
|
||||
}
|
||||
|
||||
void test_GetHeader() {
|
||||
Azure::Core::Http::Request request(Azure::Core::Http::Get, Azure::Core::Url("http://example.com"));
|
||||
{
|
||||
auto headerValue = request.GetHeader("Content-Type").Value();
|
||||
sink(headerValue); // $ ir
|
||||
}
|
||||
{
|
||||
std::map<std::string, std::string> headers = request.GetHeaders();
|
||||
std::string contentType = headers["Content-Type"];
|
||||
sink(contentType); // $ ir
|
||||
}
|
||||
}
|
||||
@@ -14,111 +14,45 @@ models
|
||||
| 13 | Source: ; ; false; NtReadFile; ; ; Argument[*5]; local; manual |
|
||||
| 14 | Source: ; ; false; ReadFile; ; ; Argument[*1]; local; manual |
|
||||
| 15 | Source: ; ; false; ReadFileEx; ; ; Argument[*1]; local; manual |
|
||||
| 16 | Source: ; ; false; WinHttpQueryHeaders; ; ; Argument[*3]; remote; manual |
|
||||
| 17 | Source: ; ; false; WinHttpQueryHeadersEx; ; ; Argument[**8]; remote; manual |
|
||||
| 18 | Source: ; ; false; WinHttpQueryHeadersEx; ; ; Argument[*5]; remote; manual |
|
||||
| 19 | Source: ; ; false; WinHttpQueryHeadersEx; ; ; Argument[*6]; remote; manual |
|
||||
| 20 | Source: ; ; false; WinHttpReadData; ; ; Argument[*1]; remote; manual |
|
||||
| 21 | Source: ; ; false; WinHttpReadDataEx; ; ; Argument[*1]; remote; manual |
|
||||
| 22 | Source: ; ; false; ymlSource; ; ; ReturnValue; local; manual |
|
||||
| 23 | Source: Azure::Core::Http; RawResponse; true; ExtractBodyStream; ; ; ReturnValue[*]; remote; manual |
|
||||
| 24 | Source: Azure::Core::Http; RawResponse; true; GetBody; ; ; ReturnValue[*]; remote; manual |
|
||||
| 25 | Source: Azure::Core::Http; RawResponse; true; GetHeaders; ; ; ReturnValue[*]; remote; manual |
|
||||
| 26 | Source: Azure::Core::Http; Request; true; GetBodyStream; ; ; ReturnValue[*]; remote; manual |
|
||||
| 27 | Source: Azure::Core::Http; Request; true; GetHeader; ; ; ReturnValue; remote; manual |
|
||||
| 28 | Source: Azure::Core::Http; Request; true; GetHeaders; ; ; ReturnValue; remote; manual |
|
||||
| 29 | Source: boost::asio; ; false; read_until; ; ; Argument[*1]; remote; manual |
|
||||
| 30 | Summary: ; ; false; CommandLineToArgvA; ; ; Argument[*0]; ReturnValue[**]; taint; manual |
|
||||
| 31 | Summary: ; ; false; CreateRemoteThread; ; ; Argument[@4]; Argument[3].Parameter[@0]; value; manual |
|
||||
| 32 | Summary: ; ; false; CreateRemoteThreadEx; ; ; Argument[@4]; Argument[3].Parameter[@0]; value; manual |
|
||||
| 33 | Summary: ; ; false; CreateThread; ; ; Argument[@3]; Argument[2].Parameter[@0]; value; manual |
|
||||
| 34 | Summary: ; ; false; ReadFileEx; ; ; Argument[*3].Field[@hEvent]; Argument[4].Parameter[*2].Field[@hEvent]; value; manual |
|
||||
| 35 | Summary: ; ; false; RtlCopyDeviceMemory; ; ; Argument[*@1]; Argument[*@0]; value; manual |
|
||||
| 36 | Summary: ; ; false; RtlCopyMemory; ; ; Argument[*@1]; Argument[*@0]; value; manual |
|
||||
| 37 | Summary: ; ; false; RtlCopyMemoryNonTemporal; ; ; Argument[*@1]; Argument[*@0]; value; manual |
|
||||
| 38 | Summary: ; ; false; RtlCopyUnicodeString; ; ; Argument[*1].Field[*Buffer]; Argument[*0].Field[*Buffer]; value; manual |
|
||||
| 39 | Summary: ; ; false; RtlCopyVolatileMemory; ; ; Argument[*@1]; Argument[*@0]; value; manual |
|
||||
| 40 | Summary: ; ; false; RtlInitUnicodeString; ; ; Argument[*1]; Argument[*0].Field[*Buffer]; value; manual |
|
||||
| 41 | Summary: ; ; false; RtlMoveMemory; ; ; Argument[*@1]; Argument[*@0]; value; manual |
|
||||
| 42 | Summary: ; ; false; RtlMoveVolatileMemory; ; ; Argument[*@1]; Argument[*@0]; value; manual |
|
||||
| 43 | Summary: ; ; false; WinHttpCrackUrl; ; ; Argument[*0]; Argument[*3]; taint; manual |
|
||||
| 44 | Summary: ; ; false; callWithArgument; ; ; Argument[1]; Argument[0].Parameter[0]; value; manual |
|
||||
| 45 | Summary: ; ; false; callWithNonTypeTemplate<T>; (const T &); ; Argument[*0]; ReturnValue; value; manual |
|
||||
| 46 | Summary: ; ; false; pthread_create; ; ; Argument[@3]; Argument[2].Parameter[@0]; value; manual |
|
||||
| 47 | Summary: ; ; false; ymlStepGenerated; ; ; Argument[0]; ReturnValue; taint; df-generated |
|
||||
| 48 | Summary: ; ; false; ymlStepManual; ; ; Argument[0]; ReturnValue; taint; manual |
|
||||
| 49 | Summary: ; ; false; ymlStepManual_with_body; ; ; Argument[0]; ReturnValue; taint; manual |
|
||||
| 50 | Summary: Azure::Core::IO; BodyStream; true; Read; ; ; Argument[-1]; Argument[*0]; taint; manual |
|
||||
| 51 | Summary: Azure::Core::IO; BodyStream; true; ReadToCount; ; ; Argument[-1]; Argument[*0]; taint; manual |
|
||||
| 52 | Summary: Azure::Core::IO; BodyStream; true; ReadToEnd; ; ; Argument[-1]; ReturnValue.Element; taint; manual |
|
||||
| 53 | Summary: Azure; Nullable; true; Value; ; ; Argument[-1]; ReturnValue[*]; taint; manual |
|
||||
| 54 | Summary: boost::asio; ; false; buffer; ; ; Argument[*0]; ReturnValue; taint; manual |
|
||||
| 16 | Source: ; ; false; ymlSource; ; ; ReturnValue; local; manual |
|
||||
| 17 | Source: boost::asio; ; false; read_until; ; ; Argument[*1]; remote; manual |
|
||||
| 18 | Summary: ; ; false; CommandLineToArgvA; ; ; Argument[*0]; ReturnValue[**]; taint; manual |
|
||||
| 19 | Summary: ; ; false; CreateRemoteThread; ; ; Argument[@4]; Argument[3].Parameter[@0]; value; manual |
|
||||
| 20 | Summary: ; ; false; CreateRemoteThreadEx; ; ; Argument[@4]; Argument[3].Parameter[@0]; value; manual |
|
||||
| 21 | Summary: ; ; false; CreateThread; ; ; Argument[@3]; Argument[2].Parameter[@0]; value; manual |
|
||||
| 22 | Summary: ; ; false; ReadFileEx; ; ; Argument[*3].Field[@hEvent]; Argument[4].Parameter[*2].Field[@hEvent]; value; manual |
|
||||
| 23 | Summary: ; ; false; RtlCopyDeviceMemory; ; ; Argument[*@1]; Argument[*@0]; value; manual |
|
||||
| 24 | Summary: ; ; false; RtlCopyMemory; ; ; Argument[*@1]; Argument[*@0]; value; manual |
|
||||
| 25 | Summary: ; ; false; RtlCopyMemoryNonTemporal; ; ; Argument[*@1]; Argument[*@0]; value; manual |
|
||||
| 26 | Summary: ; ; false; RtlCopyUnicodeString; ; ; Argument[*1].Field[*Buffer]; Argument[*0].Field[*Buffer]; value; manual |
|
||||
| 27 | Summary: ; ; false; RtlCopyVolatileMemory; ; ; Argument[*@1]; Argument[*@0]; value; manual |
|
||||
| 28 | Summary: ; ; false; RtlInitUnicodeString; ; ; Argument[*1]; Argument[*0].Field[*Buffer]; value; manual |
|
||||
| 29 | Summary: ; ; false; RtlMoveMemory; ; ; Argument[*@1]; Argument[*@0]; value; manual |
|
||||
| 30 | Summary: ; ; false; RtlMoveVolatileMemory; ; ; Argument[*@1]; Argument[*@0]; value; manual |
|
||||
| 31 | Summary: ; ; false; callWithArgument; ; ; Argument[1]; Argument[0].Parameter[0]; value; manual |
|
||||
| 32 | Summary: ; ; false; callWithNonTypeTemplate<T>; (const T &); ; Argument[*0]; ReturnValue; value; manual |
|
||||
| 33 | Summary: ; ; false; pthread_create; ; ; Argument[@3]; Argument[2].Parameter[@0]; value; manual |
|
||||
| 34 | Summary: ; ; false; ymlStepGenerated; ; ; Argument[0]; ReturnValue; taint; df-generated |
|
||||
| 35 | Summary: ; ; false; ymlStepManual; ; ; Argument[0]; ReturnValue; taint; manual |
|
||||
| 36 | Summary: ; ; false; ymlStepManual_with_body; ; ; Argument[0]; ReturnValue; taint; manual |
|
||||
| 37 | Summary: boost::asio; ; false; buffer; ; ; Argument[*0]; ReturnValue; taint; manual |
|
||||
edges
|
||||
| asio_streams.cpp:56:18:56:23 | [summary param] *0 in buffer | asio_streams.cpp:56:18:56:23 | [summary] to write: ReturnValue in buffer | provenance | MaD:54 |
|
||||
| asio_streams.cpp:87:34:87:44 | read_until output argument | asio_streams.cpp:91:7:91:17 | recv_buffer | provenance | Src:MaD:29 |
|
||||
| asio_streams.cpp:87:34:87:44 | read_until output argument | asio_streams.cpp:93:29:93:39 | *recv_buffer | provenance | Src:MaD:29 Sink:MaD:2 |
|
||||
| asio_streams.cpp:56:18:56:23 | [summary param] *0 in buffer | asio_streams.cpp:56:18:56:23 | [summary] to write: ReturnValue in buffer | provenance | MaD:37 |
|
||||
| asio_streams.cpp:87:34:87:44 | read_until output argument | asio_streams.cpp:91:7:91:17 | recv_buffer | provenance | Src:MaD:17 |
|
||||
| asio_streams.cpp:87:34:87:44 | read_until output argument | asio_streams.cpp:93:29:93:39 | *recv_buffer | provenance | Src:MaD:17 Sink:MaD:2 |
|
||||
| asio_streams.cpp:97:37:97:44 | call to source | asio_streams.cpp:98:7:98:14 | send_str | provenance | TaintFunction |
|
||||
| asio_streams.cpp:97:37:97:44 | call to source | asio_streams.cpp:100:64:100:71 | *send_str | provenance | TaintFunction |
|
||||
| asio_streams.cpp:100:44:100:62 | call to buffer | asio_streams.cpp:100:44:100:62 | call to buffer | provenance | |
|
||||
| asio_streams.cpp:100:44:100:62 | call to buffer | asio_streams.cpp:101:7:101:17 | send_buffer | provenance | |
|
||||
| asio_streams.cpp:100:44:100:62 | call to buffer | asio_streams.cpp:103:29:103:39 | *send_buffer | provenance | Sink:MaD:2 |
|
||||
| asio_streams.cpp:100:64:100:71 | *send_str | asio_streams.cpp:56:18:56:23 | [summary param] *0 in buffer | provenance | |
|
||||
| asio_streams.cpp:100:64:100:71 | *send_str | asio_streams.cpp:100:44:100:62 | call to buffer | provenance | MaD:54 |
|
||||
| azure.cpp:62:10:62:14 | [summary param] this in Value | azure.cpp:62:10:62:14 | [summary] to write: ReturnValue[*] in Value | provenance | MaD:53 |
|
||||
| azure.cpp:113:16:113:19 | [summary param] this in Read | azure.cpp:113:16:113:19 | [summary param] *0 in Read [Return] | provenance | MaD:50 |
|
||||
| azure.cpp:114:16:114:26 | [summary param] this in ReadToCount | azure.cpp:114:16:114:26 | [summary param] *0 in ReadToCount [Return] | provenance | MaD:51 |
|
||||
| azure.cpp:115:30:115:38 | [summary param] this in ReadToEnd | azure.cpp:115:30:115:38 | [summary] to write: ReturnValue.Element in ReadToEnd | provenance | MaD:52 |
|
||||
| azure.cpp:115:30:115:38 | [summary] to write: ReturnValue.Element in ReadToEnd | azure.cpp:115:30:115:38 | [summary] to write: ReturnValue in ReadToEnd [element] | provenance | |
|
||||
| azure.cpp:253:48:253:60 | *call to GetBodyStream | azure.cpp:253:48:253:60 | *call to GetBodyStream | provenance | Src:MaD:26 |
|
||||
| azure.cpp:253:48:253:60 | *call to GetBodyStream | azure.cpp:257:5:257:8 | *resp | provenance | |
|
||||
| azure.cpp:253:48:253:60 | *call to GetBodyStream | azure.cpp:262:5:262:8 | *resp | provenance | |
|
||||
| azure.cpp:253:48:253:60 | *call to GetBodyStream | azure.cpp:266:38:266:41 | *resp | provenance | |
|
||||
| azure.cpp:257:5:257:8 | *resp | azure.cpp:113:16:113:19 | [summary param] this in Read | provenance | |
|
||||
| azure.cpp:257:5:257:8 | *resp | azure.cpp:257:16:257:21 | Read output argument | provenance | MaD:50 |
|
||||
| azure.cpp:257:16:257:21 | Read output argument | azure.cpp:258:10:258:16 | * ... | provenance | |
|
||||
| azure.cpp:262:5:262:8 | *resp | azure.cpp:114:16:114:26 | [summary param] this in ReadToCount | provenance | |
|
||||
| azure.cpp:262:5:262:8 | *resp | azure.cpp:262:23:262:28 | ReadToCount output argument | provenance | MaD:51 |
|
||||
| azure.cpp:262:23:262:28 | ReadToCount output argument | azure.cpp:263:10:263:16 | * ... | provenance | |
|
||||
| azure.cpp:266:38:266:41 | *resp | azure.cpp:115:30:115:38 | [summary param] this in ReadToEnd | provenance | |
|
||||
| azure.cpp:266:38:266:41 | *resp | azure.cpp:266:44:266:52 | call to ReadToEnd [element] | provenance | MaD:52 |
|
||||
| azure.cpp:266:44:266:52 | call to ReadToEnd [element] | azure.cpp:266:44:266:52 | call to ReadToEnd [element] | provenance | |
|
||||
| azure.cpp:266:44:266:52 | call to ReadToEnd [element] | azure.cpp:267:10:267:12 | vec [element] | provenance | |
|
||||
| azure.cpp:267:10:267:12 | vec [element] | azure.cpp:267:10:267:12 | vec | provenance | |
|
||||
| azure.cpp:273:62:273:64 | call to GetHeaders | azure.cpp:273:62:273:64 | call to GetHeaders | provenance | Src:MaD:25 |
|
||||
| azure.cpp:273:62:273:64 | call to GetHeaders | azure.cpp:274:14:274:29 | call to operator[] | provenance | TaintFunction |
|
||||
| azure.cpp:273:62:273:64 | call to GetHeaders | azure.cpp:274:14:274:29 | call to operator[] | provenance | TaintFunction |
|
||||
| azure.cpp:273:62:273:64 | call to GetHeaders | azure.cpp:274:14:274:29 | call to operator[] | provenance | TaintFunction |
|
||||
| azure.cpp:274:14:274:29 | call to operator[] | azure.cpp:274:10:274:29 | call to operator[] | provenance | |
|
||||
| azure.cpp:274:14:274:29 | call to operator[] | azure.cpp:274:14:274:29 | call to operator[] | provenance | |
|
||||
| azure.cpp:277:45:277:47 | call to GetBody | azure.cpp:277:45:277:47 | call to GetBody | provenance | Src:MaD:24 |
|
||||
| azure.cpp:277:45:277:47 | call to GetBody | azure.cpp:278:10:278:13 | body | provenance | |
|
||||
| azure.cpp:277:45:277:47 | call to GetBody | azure.cpp:278:10:278:13 | body | provenance | |
|
||||
| azure.cpp:278:10:278:13 | body | azure.cpp:278:10:278:13 | body | provenance | |
|
||||
| azure.cpp:281:68:281:84 | *call to ExtractBodyStream | azure.cpp:281:68:281:84 | *call to ExtractBodyStream | provenance | Src:MaD:23 |
|
||||
| azure.cpp:281:68:281:84 | *call to ExtractBodyStream | azure.cpp:282:21:282:23 | *call to get | provenance | |
|
||||
| azure.cpp:282:21:282:23 | *call to get | azure.cpp:115:30:115:38 | [summary param] this in ReadToEnd | provenance | |
|
||||
| azure.cpp:282:21:282:23 | *call to get | azure.cpp:282:28:282:36 | call to ReadToEnd [element] | provenance | MaD:52 |
|
||||
| azure.cpp:282:28:282:36 | call to ReadToEnd [element] | azure.cpp:282:10:282:38 | call to ReadToEnd | provenance | |
|
||||
| azure.cpp:282:28:282:36 | call to ReadToEnd [element] | azure.cpp:282:28:282:36 | call to ReadToEnd [element] | provenance | |
|
||||
| azure.cpp:289:24:289:56 | call to GetHeader | azure.cpp:62:10:62:14 | [summary param] this in Value | provenance | |
|
||||
| azure.cpp:289:24:289:56 | call to GetHeader | azure.cpp:289:63:289:65 | call to Value | provenance | MaD:53 |
|
||||
| azure.cpp:289:32:289:40 | call to GetHeader | azure.cpp:289:24:289:56 | call to GetHeader | provenance | |
|
||||
| azure.cpp:289:32:289:40 | call to GetHeader | azure.cpp:289:32:289:40 | call to GetHeader | provenance | Src:MaD:27 |
|
||||
| azure.cpp:289:63:289:65 | call to Value | azure.cpp:289:63:289:65 | call to Value | provenance | |
|
||||
| azure.cpp:289:63:289:65 | call to Value | azure.cpp:290:10:290:20 | headerValue | provenance | |
|
||||
| azure.cpp:289:63:289:65 | call to Value | azure.cpp:290:10:290:20 | headerValue | provenance | |
|
||||
| azure.cpp:290:10:290:20 | headerValue | azure.cpp:290:10:290:20 | headerValue | provenance | |
|
||||
| azure.cpp:293:58:293:67 | call to GetHeaders | azure.cpp:293:58:293:67 | call to GetHeaders | provenance | Src:MaD:28 |
|
||||
| azure.cpp:293:58:293:67 | call to GetHeaders | azure.cpp:294:38:294:53 | call to operator[] | provenance | TaintFunction |
|
||||
| azure.cpp:294:38:294:53 | call to operator[] | azure.cpp:295:10:295:20 | contentType | provenance | |
|
||||
| azure.cpp:294:38:294:53 | call to operator[] | azure.cpp:295:10:295:20 | contentType | provenance | |
|
||||
| azure.cpp:295:10:295:20 | contentType | azure.cpp:295:10:295:20 | contentType | provenance | |
|
||||
| test.cpp:4:5:4:17 | [summary param] 0 in ymlStepManual | test.cpp:4:5:4:17 | [summary] to write: ReturnValue in ymlStepManual | provenance | MaD:48 |
|
||||
| test.cpp:5:5:5:20 | [summary param] 0 in ymlStepGenerated | test.cpp:5:5:5:20 | [summary] to write: ReturnValue in ymlStepGenerated | provenance | MaD:47 |
|
||||
| test.cpp:6:5:6:27 | [summary param] 0 in ymlStepManual_with_body | test.cpp:6:5:6:27 | [summary] to write: ReturnValue in ymlStepManual_with_body | provenance | MaD:49 |
|
||||
| asio_streams.cpp:100:64:100:71 | *send_str | asio_streams.cpp:100:44:100:62 | call to buffer | provenance | MaD:37 |
|
||||
| test.cpp:4:5:4:17 | [summary param] 0 in ymlStepManual | test.cpp:4:5:4:17 | [summary] to write: ReturnValue in ymlStepManual | provenance | MaD:35 |
|
||||
| test.cpp:5:5:5:20 | [summary param] 0 in ymlStepGenerated | test.cpp:5:5:5:20 | [summary] to write: ReturnValue in ymlStepGenerated | provenance | MaD:34 |
|
||||
| test.cpp:6:5:6:27 | [summary param] 0 in ymlStepManual_with_body | test.cpp:6:5:6:27 | [summary] to write: ReturnValue in ymlStepManual_with_body | provenance | MaD:36 |
|
||||
| test.cpp:7:47:7:52 | value2 | test.cpp:7:64:7:69 | value2 | provenance | |
|
||||
| test.cpp:7:64:7:69 | value2 | test.cpp:7:5:7:30 | *ymlStepGenerated_with_body | provenance | |
|
||||
| test.cpp:10:10:10:18 | call to ymlSource | test.cpp:10:10:10:18 | call to ymlSource | provenance | Src:MaD:22 |
|
||||
| test.cpp:10:10:10:18 | call to ymlSource | test.cpp:10:10:10:18 | call to ymlSource | provenance | Src:MaD:16 |
|
||||
| test.cpp:10:10:10:18 | call to ymlSource | test.cpp:14:10:14:10 | x | provenance | Sink:MaD:1 |
|
||||
| test.cpp:10:10:10:18 | call to ymlSource | test.cpp:17:24:17:24 | x | provenance | |
|
||||
| test.cpp:10:10:10:18 | call to ymlSource | test.cpp:21:27:21:27 | x | provenance | |
|
||||
@@ -127,15 +61,15 @@ edges
|
||||
| test.cpp:17:10:17:22 | call to ymlStepManual | test.cpp:17:10:17:22 | call to ymlStepManual | provenance | |
|
||||
| test.cpp:17:10:17:22 | call to ymlStepManual | test.cpp:18:10:18:10 | y | provenance | Sink:MaD:1 |
|
||||
| test.cpp:17:24:17:24 | x | test.cpp:4:5:4:17 | [summary param] 0 in ymlStepManual | provenance | |
|
||||
| test.cpp:17:24:17:24 | x | test.cpp:17:10:17:22 | call to ymlStepManual | provenance | MaD:48 |
|
||||
| test.cpp:17:24:17:24 | x | test.cpp:17:10:17:22 | call to ymlStepManual | provenance | MaD:35 |
|
||||
| test.cpp:21:10:21:25 | call to ymlStepGenerated | test.cpp:21:10:21:25 | call to ymlStepGenerated | provenance | |
|
||||
| test.cpp:21:10:21:25 | call to ymlStepGenerated | test.cpp:22:10:22:10 | z | provenance | Sink:MaD:1 |
|
||||
| test.cpp:21:27:21:27 | x | test.cpp:5:5:5:20 | [summary param] 0 in ymlStepGenerated | provenance | |
|
||||
| test.cpp:21:27:21:27 | x | test.cpp:21:10:21:25 | call to ymlStepGenerated | provenance | MaD:47 |
|
||||
| test.cpp:21:27:21:27 | x | test.cpp:21:10:21:25 | call to ymlStepGenerated | provenance | MaD:34 |
|
||||
| test.cpp:25:11:25:33 | call to ymlStepManual_with_body | test.cpp:25:11:25:33 | call to ymlStepManual_with_body | provenance | |
|
||||
| test.cpp:25:11:25:33 | call to ymlStepManual_with_body | test.cpp:26:10:26:11 | y2 | provenance | Sink:MaD:1 |
|
||||
| test.cpp:25:35:25:35 | x | test.cpp:6:5:6:27 | [summary param] 0 in ymlStepManual_with_body | provenance | |
|
||||
| test.cpp:25:35:25:35 | x | test.cpp:25:11:25:33 | call to ymlStepManual_with_body | provenance | MaD:49 |
|
||||
| test.cpp:25:35:25:35 | x | test.cpp:25:11:25:33 | call to ymlStepManual_with_body | provenance | MaD:36 |
|
||||
| test.cpp:32:11:32:36 | call to ymlStepGenerated_with_body | test.cpp:32:11:32:36 | call to ymlStepGenerated_with_body | provenance | |
|
||||
| test.cpp:32:11:32:36 | call to ymlStepGenerated_with_body | test.cpp:33:10:33:11 | z2 | provenance | Sink:MaD:1 |
|
||||
| test.cpp:32:41:32:41 | x | test.cpp:7:47:7:52 | value2 | provenance | |
|
||||
@@ -143,16 +77,16 @@ edges
|
||||
| test.cpp:46:30:46:32 | *arg [x] | test.cpp:47:12:47:19 | *arg [x] | provenance | |
|
||||
| test.cpp:47:12:47:19 | *arg [x] | test.cpp:48:13:48:13 | *s [x] | provenance | |
|
||||
| test.cpp:48:13:48:13 | *s [x] | test.cpp:48:16:48:16 | x | provenance | Sink:MaD:1 |
|
||||
| test.cpp:52:5:52:18 | [summary param] *3 in pthread_create [x] | test.cpp:52:5:52:18 | [summary] to write: Argument[2].Parameter[*0] in pthread_create [x] | provenance | MaD:46 |
|
||||
| test.cpp:52:5:52:18 | [summary param] *3 in pthread_create [x] | test.cpp:52:5:52:18 | [summary] to write: Argument[2].Parameter[*0] in pthread_create [x] | provenance | MaD:33 |
|
||||
| test.cpp:52:5:52:18 | [summary] to write: Argument[2].Parameter[*0] in pthread_create [x] | test.cpp:46:30:46:32 | *arg [x] | provenance | |
|
||||
| test.cpp:56:2:56:2 | *s [post update] [x] | test.cpp:59:55:59:64 | *& ... [x] | provenance | |
|
||||
| test.cpp:56:2:56:18 | ... = ... | test.cpp:56:2:56:2 | *s [post update] [x] | provenance | |
|
||||
| test.cpp:56:8:56:16 | call to ymlSource | test.cpp:56:2:56:18 | ... = ... | provenance | Src:MaD:22 |
|
||||
| test.cpp:56:8:56:16 | call to ymlSource | test.cpp:56:2:56:18 | ... = ... | provenance | Src:MaD:16 |
|
||||
| test.cpp:59:55:59:64 | *& ... [x] | test.cpp:52:5:52:18 | [summary param] *3 in pthread_create [x] | provenance | |
|
||||
| test.cpp:63:6:63:21 | [summary param] 1 in callWithArgument | test.cpp:63:6:63:21 | [summary] to write: Argument[0].Parameter[0] in callWithArgument | provenance | MaD:44 |
|
||||
| test.cpp:63:6:63:21 | [summary param] 1 in callWithArgument | test.cpp:63:6:63:21 | [summary] to write: Argument[0].Parameter[0] in callWithArgument | provenance | MaD:44 |
|
||||
| test.cpp:63:6:63:21 | [summary param] 1 in callWithArgument | test.cpp:63:6:63:21 | [summary] to write: Argument[0].Parameter[0] in callWithArgument | provenance | MaD:44 |
|
||||
| test.cpp:63:6:63:21 | [summary param] 1 in callWithArgument | test.cpp:63:6:63:21 | [summary] to write: Argument[0].Parameter[0] in callWithArgument | provenance | MaD:44 |
|
||||
| test.cpp:63:6:63:21 | [summary param] 1 in callWithArgument | test.cpp:63:6:63:21 | [summary] to write: Argument[0].Parameter[0] in callWithArgument | provenance | MaD:31 |
|
||||
| test.cpp:63:6:63:21 | [summary param] 1 in callWithArgument | test.cpp:63:6:63:21 | [summary] to write: Argument[0].Parameter[0] in callWithArgument | provenance | MaD:31 |
|
||||
| test.cpp:63:6:63:21 | [summary param] 1 in callWithArgument | test.cpp:63:6:63:21 | [summary] to write: Argument[0].Parameter[0] in callWithArgument | provenance | MaD:31 |
|
||||
| test.cpp:63:6:63:21 | [summary param] 1 in callWithArgument | test.cpp:63:6:63:21 | [summary] to write: Argument[0].Parameter[0] in callWithArgument | provenance | MaD:31 |
|
||||
| test.cpp:63:6:63:21 | [summary] to write: Argument[0].Parameter[0] in callWithArgument | test.cpp:68:22:68:22 | y | provenance | |
|
||||
| test.cpp:63:6:63:21 | [summary] to write: Argument[0].Parameter[0] in callWithArgument | test.cpp:74:22:74:22 | y | provenance | |
|
||||
| test.cpp:63:6:63:21 | [summary] to write: Argument[0].Parameter[0] in callWithArgument | test.cpp:82:22:82:22 | y | provenance | |
|
||||
@@ -161,7 +95,7 @@ edges
|
||||
| test.cpp:74:22:74:22 | y | test.cpp:75:11:75:11 | y | provenance | Sink:MaD:1 |
|
||||
| test.cpp:82:22:82:22 | y | test.cpp:83:11:83:11 | y | provenance | Sink:MaD:1 |
|
||||
| test.cpp:88:22:88:22 | y | test.cpp:89:11:89:11 | y | provenance | Sink:MaD:1 |
|
||||
| test.cpp:94:10:94:18 | call to ymlSource | test.cpp:94:10:94:18 | call to ymlSource | provenance | Src:MaD:22 |
|
||||
| test.cpp:94:10:94:18 | call to ymlSource | test.cpp:94:10:94:18 | call to ymlSource | provenance | Src:MaD:16 |
|
||||
| test.cpp:94:10:94:18 | call to ymlSource | test.cpp:97:26:97:26 | x | provenance | |
|
||||
| test.cpp:94:10:94:18 | call to ymlSource | test.cpp:101:26:101:26 | x | provenance | |
|
||||
| test.cpp:94:10:94:18 | call to ymlSource | test.cpp:103:63:103:63 | x | provenance | |
|
||||
@@ -170,28 +104,28 @@ edges
|
||||
| test.cpp:101:26:101:26 | x | test.cpp:63:6:63:21 | [summary param] 1 in callWithArgument | provenance | |
|
||||
| test.cpp:103:63:103:63 | x | test.cpp:63:6:63:21 | [summary param] 1 in callWithArgument | provenance | |
|
||||
| test.cpp:104:62:104:62 | x | test.cpp:63:6:63:21 | [summary param] 1 in callWithArgument | provenance | |
|
||||
| test.cpp:111:3:111:25 | [summary param] *0 in callWithNonTypeTemplate | test.cpp:111:3:111:25 | [summary] to write: ReturnValue in callWithNonTypeTemplate | provenance | MaD:45 |
|
||||
| test.cpp:114:10:114:18 | call to ymlSource | test.cpp:114:10:114:18 | call to ymlSource | provenance | Src:MaD:22 |
|
||||
| test.cpp:111:3:111:25 | [summary param] *0 in callWithNonTypeTemplate | test.cpp:111:3:111:25 | [summary] to write: ReturnValue in callWithNonTypeTemplate | provenance | MaD:32 |
|
||||
| test.cpp:114:10:114:18 | call to ymlSource | test.cpp:114:10:114:18 | call to ymlSource | provenance | Src:MaD:16 |
|
||||
| test.cpp:114:10:114:18 | call to ymlSource | test.cpp:118:44:118:44 | *x | provenance | |
|
||||
| test.cpp:118:11:118:42 | call to callWithNonTypeTemplate | test.cpp:118:11:118:42 | call to callWithNonTypeTemplate | provenance | |
|
||||
| test.cpp:118:11:118:42 | call to callWithNonTypeTemplate | test.cpp:119:10:119:11 | y2 | provenance | Sink:MaD:1 |
|
||||
| test.cpp:118:44:118:44 | *x | test.cpp:111:3:111:25 | [summary param] *0 in callWithNonTypeTemplate | provenance | |
|
||||
| test.cpp:118:44:118:44 | *x | test.cpp:118:11:118:42 | call to callWithNonTypeTemplate | provenance | MaD:45 |
|
||||
| windows.cpp:17:8:17:25 | [summary param] *0 in CommandLineToArgvA | windows.cpp:17:8:17:25 | [summary] to write: ReturnValue[**] in CommandLineToArgvA | provenance | MaD:30 |
|
||||
| test.cpp:118:44:118:44 | *x | test.cpp:118:11:118:42 | call to callWithNonTypeTemplate | provenance | MaD:32 |
|
||||
| windows.cpp:17:8:17:25 | [summary param] *0 in CommandLineToArgvA | windows.cpp:17:8:17:25 | [summary] to write: ReturnValue[**] in CommandLineToArgvA | provenance | MaD:18 |
|
||||
| windows.cpp:22:15:22:29 | *call to GetCommandLineA | windows.cpp:22:15:22:29 | *call to GetCommandLineA | provenance | Src:MaD:3 |
|
||||
| windows.cpp:22:15:22:29 | *call to GetCommandLineA | windows.cpp:24:8:24:11 | * ... | provenance | |
|
||||
| windows.cpp:22:15:22:29 | *call to GetCommandLineA | windows.cpp:27:36:27:38 | *cmd | provenance | |
|
||||
| windows.cpp:27:17:27:34 | **call to CommandLineToArgvA | windows.cpp:27:17:27:34 | **call to CommandLineToArgvA | provenance | |
|
||||
| windows.cpp:27:17:27:34 | **call to CommandLineToArgvA | windows.cpp:30:8:30:15 | * ... | provenance | |
|
||||
| windows.cpp:27:36:27:38 | *cmd | windows.cpp:17:8:17:25 | [summary param] *0 in CommandLineToArgvA | provenance | |
|
||||
| windows.cpp:27:36:27:38 | *cmd | windows.cpp:27:17:27:34 | **call to CommandLineToArgvA | provenance | MaD:30 |
|
||||
| windows.cpp:27:36:27:38 | *cmd | windows.cpp:27:17:27:34 | **call to CommandLineToArgvA | provenance | MaD:18 |
|
||||
| windows.cpp:34:17:34:38 | *call to GetEnvironmentStringsA | windows.cpp:34:17:34:38 | *call to GetEnvironmentStringsA | provenance | Src:MaD:4 |
|
||||
| windows.cpp:34:17:34:38 | *call to GetEnvironmentStringsA | windows.cpp:36:10:36:13 | * ... | provenance | |
|
||||
| windows.cpp:39:36:39:38 | GetEnvironmentVariableA output argument | windows.cpp:41:10:41:13 | * ... | provenance | Src:MaD:5 |
|
||||
| windows.cpp:90:6:90:15 | [summary param] *3 in ReadFileEx [*hEvent] | windows.cpp:90:6:90:15 | [summary] read: Argument[*3].Field[*hEvent] in ReadFileEx | provenance | |
|
||||
| windows.cpp:90:6:90:15 | [summary param] *3 in ReadFileEx [hEvent] | windows.cpp:90:6:90:15 | [summary] read: Argument[*3].Field[hEvent] in ReadFileEx | provenance | |
|
||||
| windows.cpp:90:6:90:15 | [summary] read: Argument[*3].Field[*hEvent] in ReadFileEx | windows.cpp:90:6:90:15 | [summary] to write: Argument[4].Parameter[*2].Field[*hEvent] in ReadFileEx | provenance | MaD:34 |
|
||||
| windows.cpp:90:6:90:15 | [summary] read: Argument[*3].Field[hEvent] in ReadFileEx | windows.cpp:90:6:90:15 | [summary] to write: Argument[4].Parameter[*2].Field[hEvent] in ReadFileEx | provenance | MaD:34 |
|
||||
| windows.cpp:90:6:90:15 | [summary] read: Argument[*3].Field[*hEvent] in ReadFileEx | windows.cpp:90:6:90:15 | [summary] to write: Argument[4].Parameter[*2].Field[*hEvent] in ReadFileEx | provenance | MaD:22 |
|
||||
| windows.cpp:90:6:90:15 | [summary] read: Argument[*3].Field[hEvent] in ReadFileEx | windows.cpp:90:6:90:15 | [summary] to write: Argument[4].Parameter[*2].Field[hEvent] in ReadFileEx | provenance | MaD:22 |
|
||||
| windows.cpp:90:6:90:15 | [summary] to write: Argument[4].Parameter[*2] in ReadFileEx [*hEvent] | windows.cpp:147:16:147:27 | *lpOverlapped [*hEvent] | provenance | |
|
||||
| windows.cpp:90:6:90:15 | [summary] to write: Argument[4].Parameter[*2] in ReadFileEx [hEvent] | windows.cpp:157:16:157:27 | *lpOverlapped [hEvent] | provenance | |
|
||||
| windows.cpp:90:6:90:15 | [summary] to write: Argument[4].Parameter[*2].Field[*hEvent] in ReadFileEx | windows.cpp:90:6:90:15 | [summary] to write: Argument[4].Parameter[*2] in ReadFileEx [*hEvent] | provenance | |
|
||||
@@ -239,11 +173,11 @@ edges
|
||||
| windows.cpp:332:23:332:40 | *call to MapViewOfFileNuma2 | windows.cpp:332:23:332:40 | *call to MapViewOfFileNuma2 | provenance | Src:MaD:12 |
|
||||
| windows.cpp:332:23:332:40 | *call to MapViewOfFileNuma2 | windows.cpp:333:20:333:52 | *pMapView | provenance | |
|
||||
| windows.cpp:333:20:333:52 | *pMapView | windows.cpp:335:10:335:16 | * ... | provenance | |
|
||||
| windows.cpp:349:8:349:19 | [summary param] *3 in CreateThread [x] | windows.cpp:349:8:349:19 | [summary] to write: Argument[2].Parameter[*0] in CreateThread [x] | provenance | MaD:33 |
|
||||
| windows.cpp:349:8:349:19 | [summary param] *3 in CreateThread [x] | windows.cpp:349:8:349:19 | [summary] to write: Argument[2].Parameter[*0] in CreateThread [x] | provenance | MaD:21 |
|
||||
| windows.cpp:349:8:349:19 | [summary] to write: Argument[2].Parameter[*0] in CreateThread [x] | windows.cpp:403:26:403:36 | *lpParameter [x] | provenance | |
|
||||
| windows.cpp:357:8:357:25 | [summary param] *4 in CreateRemoteThread [x] | windows.cpp:357:8:357:25 | [summary] to write: Argument[3].Parameter[*0] in CreateRemoteThread [x] | provenance | MaD:31 |
|
||||
| windows.cpp:357:8:357:25 | [summary param] *4 in CreateRemoteThread [x] | windows.cpp:357:8:357:25 | [summary] to write: Argument[3].Parameter[*0] in CreateRemoteThread [x] | provenance | MaD:19 |
|
||||
| windows.cpp:357:8:357:25 | [summary] to write: Argument[3].Parameter[*0] in CreateRemoteThread [x] | windows.cpp:410:26:410:36 | *lpParameter [x] | provenance | |
|
||||
| windows.cpp:387:8:387:27 | [summary param] *4 in CreateRemoteThreadEx [x] | windows.cpp:387:8:387:27 | [summary] to write: Argument[3].Parameter[*0] in CreateRemoteThreadEx [x] | provenance | MaD:32 |
|
||||
| windows.cpp:387:8:387:27 | [summary param] *4 in CreateRemoteThreadEx [x] | windows.cpp:387:8:387:27 | [summary] to write: Argument[3].Parameter[*0] in CreateRemoteThreadEx [x] | provenance | MaD:20 |
|
||||
| windows.cpp:387:8:387:27 | [summary] to write: Argument[3].Parameter[*0] in CreateRemoteThreadEx [x] | windows.cpp:417:26:417:36 | *lpParameter [x] | provenance | |
|
||||
| windows.cpp:403:26:403:36 | *lpParameter [x] | windows.cpp:405:10:405:25 | *lpParameter [x] | provenance | |
|
||||
| windows.cpp:405:10:405:25 | *lpParameter [x] | windows.cpp:406:8:406:8 | *s [x] | provenance | |
|
||||
@@ -262,17 +196,17 @@ edges
|
||||
| windows.cpp:439:7:439:8 | *& ... [x] | windows.cpp:349:8:349:19 | [summary param] *3 in CreateThread [x] | provenance | |
|
||||
| windows.cpp:451:7:451:8 | *& ... [x] | windows.cpp:357:8:357:25 | [summary param] *4 in CreateRemoteThread [x] | provenance | |
|
||||
| windows.cpp:464:7:464:8 | *& ... [x] | windows.cpp:387:8:387:27 | [summary param] *4 in CreateRemoteThreadEx [x] | provenance | |
|
||||
| windows.cpp:473:17:473:37 | [summary param] *1 in RtlCopyVolatileMemory | windows.cpp:473:17:473:37 | [summary param] *0 in RtlCopyVolatileMemory [Return] | provenance | MaD:39 |
|
||||
| windows.cpp:479:17:479:35 | [summary param] *1 in RtlCopyDeviceMemory | windows.cpp:479:17:479:35 | [summary param] *0 in RtlCopyDeviceMemory [Return] | provenance | MaD:35 |
|
||||
| windows.cpp:485:6:485:18 | [summary param] *1 in RtlCopyMemory | windows.cpp:485:6:485:18 | [summary param] *0 in RtlCopyMemory [Return] | provenance | MaD:36 |
|
||||
| windows.cpp:493:6:493:29 | [summary param] *1 in RtlCopyMemoryNonTemporal | windows.cpp:493:6:493:29 | [summary param] *0 in RtlCopyMemoryNonTemporal [Return] | provenance | MaD:37 |
|
||||
| windows.cpp:473:17:473:37 | [summary param] *1 in RtlCopyVolatileMemory | windows.cpp:473:17:473:37 | [summary param] *0 in RtlCopyVolatileMemory [Return] | provenance | MaD:27 |
|
||||
| windows.cpp:479:17:479:35 | [summary param] *1 in RtlCopyDeviceMemory | windows.cpp:479:17:479:35 | [summary param] *0 in RtlCopyDeviceMemory [Return] | provenance | MaD:23 |
|
||||
| windows.cpp:485:6:485:18 | [summary param] *1 in RtlCopyMemory | windows.cpp:485:6:485:18 | [summary param] *0 in RtlCopyMemory [Return] | provenance | MaD:24 |
|
||||
| windows.cpp:493:6:493:29 | [summary param] *1 in RtlCopyMemoryNonTemporal | windows.cpp:493:6:493:29 | [summary param] *0 in RtlCopyMemoryNonTemporal [Return] | provenance | MaD:25 |
|
||||
| windows.cpp:510:6:510:25 | [summary param] *1 in RtlCopyUnicodeString [*Buffer] | windows.cpp:510:6:510:25 | [summary] read: Argument[*1].Field[*Buffer] in RtlCopyUnicodeString | provenance | |
|
||||
| windows.cpp:510:6:510:25 | [summary] read: Argument[*1].Field[*Buffer] in RtlCopyUnicodeString | windows.cpp:510:6:510:25 | [summary] to write: Argument[*0].Field[*Buffer] in RtlCopyUnicodeString | provenance | MaD:38 |
|
||||
| windows.cpp:510:6:510:25 | [summary] read: Argument[*1].Field[*Buffer] in RtlCopyUnicodeString | windows.cpp:510:6:510:25 | [summary] to write: Argument[*0].Field[*Buffer] in RtlCopyUnicodeString | provenance | MaD:26 |
|
||||
| windows.cpp:510:6:510:25 | [summary] to write: Argument[*0] in RtlCopyUnicodeString [*Buffer] | windows.cpp:510:6:510:25 | [summary param] *0 in RtlCopyUnicodeString [Return] [*Buffer] | provenance | |
|
||||
| windows.cpp:510:6:510:25 | [summary] to write: Argument[*0].Field[*Buffer] in RtlCopyUnicodeString | windows.cpp:510:6:510:25 | [summary] to write: Argument[*0] in RtlCopyUnicodeString [*Buffer] | provenance | |
|
||||
| windows.cpp:515:6:515:18 | [summary param] *1 in RtlMoveMemory | windows.cpp:515:6:515:18 | [summary param] *0 in RtlMoveMemory [Return] | provenance | MaD:41 |
|
||||
| windows.cpp:521:17:521:37 | [summary param] *1 in RtlMoveVolatileMemory | windows.cpp:521:17:521:37 | [summary param] *0 in RtlMoveVolatileMemory [Return] | provenance | MaD:42 |
|
||||
| windows.cpp:527:6:527:25 | [summary param] *1 in RtlInitUnicodeString | windows.cpp:527:6:527:25 | [summary] to write: Argument[*0].Field[*Buffer] in RtlInitUnicodeString | provenance | MaD:40 |
|
||||
| windows.cpp:515:6:515:18 | [summary param] *1 in RtlMoveMemory | windows.cpp:515:6:515:18 | [summary param] *0 in RtlMoveMemory [Return] | provenance | MaD:29 |
|
||||
| windows.cpp:521:17:521:37 | [summary param] *1 in RtlMoveVolatileMemory | windows.cpp:521:17:521:37 | [summary param] *0 in RtlMoveVolatileMemory [Return] | provenance | MaD:30 |
|
||||
| windows.cpp:527:6:527:25 | [summary param] *1 in RtlInitUnicodeString | windows.cpp:527:6:527:25 | [summary] to write: Argument[*0].Field[*Buffer] in RtlInitUnicodeString | provenance | MaD:28 |
|
||||
| windows.cpp:527:6:527:25 | [summary] to write: Argument[*0] in RtlInitUnicodeString [*Buffer] | windows.cpp:527:6:527:25 | [summary param] *0 in RtlInitUnicodeString [Return] [*Buffer] | provenance | |
|
||||
| windows.cpp:527:6:527:25 | [summary] to write: Argument[*0].Field[*Buffer] in RtlInitUnicodeString | windows.cpp:527:6:527:25 | [summary] to write: Argument[*0] in RtlInitUnicodeString [*Buffer] | provenance | |
|
||||
| windows.cpp:533:11:533:16 | call to source | windows.cpp:533:11:533:16 | call to source | provenance | |
|
||||
@@ -284,51 +218,37 @@ edges
|
||||
| windows.cpp:533:11:533:16 | call to source | windows.cpp:573:40:573:41 | *& ... | provenance | |
|
||||
| windows.cpp:537:27:537:37 | RtlCopyVolatileMemory output argument | windows.cpp:538:10:538:23 | access to array | provenance | |
|
||||
| windows.cpp:537:40:537:41 | *& ... | windows.cpp:473:17:473:37 | [summary param] *1 in RtlCopyVolatileMemory | provenance | |
|
||||
| windows.cpp:537:40:537:41 | *& ... | windows.cpp:537:27:537:37 | RtlCopyVolatileMemory output argument | provenance | MaD:39 |
|
||||
| windows.cpp:537:40:537:41 | *& ... | windows.cpp:537:27:537:37 | RtlCopyVolatileMemory output argument | provenance | MaD:27 |
|
||||
| windows.cpp:542:25:542:35 | RtlCopyDeviceMemory output argument | windows.cpp:543:10:543:23 | access to array | provenance | |
|
||||
| windows.cpp:542:38:542:39 | *& ... | windows.cpp:479:17:479:35 | [summary param] *1 in RtlCopyDeviceMemory | provenance | |
|
||||
| windows.cpp:542:38:542:39 | *& ... | windows.cpp:542:25:542:35 | RtlCopyDeviceMemory output argument | provenance | MaD:35 |
|
||||
| windows.cpp:542:38:542:39 | *& ... | windows.cpp:542:25:542:35 | RtlCopyDeviceMemory output argument | provenance | MaD:23 |
|
||||
| windows.cpp:547:19:547:29 | RtlCopyMemory output argument | windows.cpp:548:10:548:23 | access to array | provenance | |
|
||||
| windows.cpp:547:32:547:33 | *& ... | windows.cpp:485:6:485:18 | [summary param] *1 in RtlCopyMemory | provenance | |
|
||||
| windows.cpp:547:32:547:33 | *& ... | windows.cpp:547:19:547:29 | RtlCopyMemory output argument | provenance | MaD:36 |
|
||||
| windows.cpp:547:32:547:33 | *& ... | windows.cpp:547:19:547:29 | RtlCopyMemory output argument | provenance | MaD:24 |
|
||||
| windows.cpp:552:30:552:40 | RtlCopyMemoryNonTemporal output argument | windows.cpp:553:10:553:23 | access to array | provenance | |
|
||||
| windows.cpp:552:43:552:44 | *& ... | windows.cpp:493:6:493:29 | [summary param] *1 in RtlCopyMemoryNonTemporal | provenance | |
|
||||
| windows.cpp:552:43:552:44 | *& ... | windows.cpp:552:30:552:40 | RtlCopyMemoryNonTemporal output argument | provenance | MaD:37 |
|
||||
| windows.cpp:552:43:552:44 | *& ... | windows.cpp:552:30:552:40 | RtlCopyMemoryNonTemporal output argument | provenance | MaD:25 |
|
||||
| windows.cpp:559:5:559:24 | ... = ... | windows.cpp:561:39:561:44 | *buffer | provenance | |
|
||||
| windows.cpp:559:17:559:24 | call to source | windows.cpp:559:5:559:24 | ... = ... | provenance | |
|
||||
| windows.cpp:561:26:561:36 | RtlInitUnicodeString output argument [*Buffer] | windows.cpp:562:10:562:19 | *src_string [*Buffer] | provenance | |
|
||||
| windows.cpp:561:26:561:36 | RtlInitUnicodeString output argument [*Buffer] | windows.cpp:563:40:563:50 | *& ... [*Buffer] | provenance | |
|
||||
| windows.cpp:561:39:561:44 | *buffer | windows.cpp:527:6:527:25 | [summary param] *1 in RtlInitUnicodeString | provenance | |
|
||||
| windows.cpp:561:39:561:44 | *buffer | windows.cpp:561:26:561:36 | RtlInitUnicodeString output argument [*Buffer] | provenance | MaD:40 |
|
||||
| windows.cpp:561:39:561:44 | *buffer | windows.cpp:561:26:561:36 | RtlInitUnicodeString output argument [*Buffer] | provenance | MaD:28 |
|
||||
| windows.cpp:562:10:562:19 | *src_string [*Buffer] | windows.cpp:562:10:562:29 | access to array | provenance | |
|
||||
| windows.cpp:562:10:562:19 | *src_string [*Buffer] | windows.cpp:562:21:562:26 | *Buffer | provenance | |
|
||||
| windows.cpp:562:21:562:26 | *Buffer | windows.cpp:562:10:562:29 | access to array | provenance | |
|
||||
| windows.cpp:563:26:563:37 | RtlCopyUnicodeString output argument [*Buffer] | windows.cpp:564:10:564:20 | *dest_string [*Buffer] | provenance | |
|
||||
| windows.cpp:563:40:563:50 | *& ... [*Buffer] | windows.cpp:510:6:510:25 | [summary param] *1 in RtlCopyUnicodeString [*Buffer] | provenance | |
|
||||
| windows.cpp:563:40:563:50 | *& ... [*Buffer] | windows.cpp:563:26:563:37 | RtlCopyUnicodeString output argument [*Buffer] | provenance | MaD:38 |
|
||||
| windows.cpp:563:40:563:50 | *& ... [*Buffer] | windows.cpp:563:26:563:37 | RtlCopyUnicodeString output argument [*Buffer] | provenance | MaD:26 |
|
||||
| windows.cpp:564:10:564:20 | *dest_string [*Buffer] | windows.cpp:564:10:564:30 | access to array | provenance | |
|
||||
| windows.cpp:564:10:564:20 | *dest_string [*Buffer] | windows.cpp:564:22:564:27 | *Buffer | provenance | |
|
||||
| windows.cpp:564:22:564:27 | *Buffer | windows.cpp:564:10:564:30 | access to array | provenance | |
|
||||
| windows.cpp:568:19:568:29 | RtlMoveMemory output argument | windows.cpp:569:10:569:23 | access to array | provenance | |
|
||||
| windows.cpp:568:32:568:33 | *& ... | windows.cpp:515:6:515:18 | [summary param] *1 in RtlMoveMemory | provenance | |
|
||||
| windows.cpp:568:32:568:33 | *& ... | windows.cpp:568:19:568:29 | RtlMoveMemory output argument | provenance | MaD:41 |
|
||||
| windows.cpp:568:32:568:33 | *& ... | windows.cpp:568:19:568:29 | RtlMoveMemory output argument | provenance | MaD:29 |
|
||||
| windows.cpp:573:27:573:37 | RtlMoveVolatileMemory output argument | windows.cpp:574:10:574:23 | access to array | provenance | |
|
||||
| windows.cpp:573:40:573:41 | *& ... | windows.cpp:521:17:521:37 | [summary param] *1 in RtlMoveVolatileMemory | provenance | |
|
||||
| windows.cpp:573:40:573:41 | *& ... | windows.cpp:573:27:573:37 | RtlMoveVolatileMemory output argument | provenance | MaD:42 |
|
||||
| windows.cpp:645:45:645:50 | WinHttpReadData output argument | windows.cpp:647:10:647:16 | * ... | provenance | Src:MaD:20 |
|
||||
| windows.cpp:652:48:652:53 | WinHttpReadDataEx output argument | windows.cpp:654:10:654:16 | * ... | provenance | Src:MaD:21 |
|
||||
| windows.cpp:659:47:659:52 | WinHttpQueryHeaders output argument | windows.cpp:661:10:661:16 | * ... | provenance | Src:MaD:16 |
|
||||
| windows.cpp:669:70:669:79 | WinHttpQueryHeadersEx output argument | windows.cpp:673:10:673:29 | * ... | provenance | Src:MaD:18 |
|
||||
| windows.cpp:669:82:669:87 | WinHttpQueryHeadersEx output argument | windows.cpp:671:10:671:16 | * ... | provenance | Src:MaD:19 |
|
||||
| windows.cpp:669:105:669:112 | WinHttpQueryHeadersEx output argument | windows.cpp:675:10:675:27 | * ... | provenance | Src:MaD:17 |
|
||||
| windows.cpp:714:6:714:20 | [summary param] *0 in WinHttpCrackUrl | windows.cpp:714:6:714:20 | [summary param] *3 in WinHttpCrackUrl [Return] | provenance | MaD:43 |
|
||||
| windows.cpp:728:5:728:28 | ... = ... | windows.cpp:729:35:729:35 | *x | provenance | |
|
||||
| windows.cpp:728:12:728:28 | call to source | windows.cpp:728:5:728:28 | ... = ... | provenance | |
|
||||
| windows.cpp:729:35:729:35 | *x | windows.cpp:714:6:714:20 | [summary param] *0 in WinHttpCrackUrl | provenance | |
|
||||
| windows.cpp:729:35:729:35 | *x | windows.cpp:729:44:729:57 | WinHttpCrackUrl output argument | provenance | MaD:43 |
|
||||
| windows.cpp:729:44:729:57 | WinHttpCrackUrl output argument | windows.cpp:731:10:731:36 | * ... | provenance | |
|
||||
| windows.cpp:729:44:729:57 | WinHttpCrackUrl output argument | windows.cpp:733:10:733:35 | * ... | provenance | |
|
||||
| windows.cpp:729:44:729:57 | WinHttpCrackUrl output argument | windows.cpp:735:10:735:37 | * ... | provenance | |
|
||||
| windows.cpp:573:40:573:41 | *& ... | windows.cpp:573:27:573:37 | RtlMoveVolatileMemory output argument | provenance | MaD:30 |
|
||||
nodes
|
||||
| asio_streams.cpp:56:18:56:23 | [summary param] *0 in buffer | semmle.label | [summary param] *0 in buffer |
|
||||
| asio_streams.cpp:56:18:56:23 | [summary] to write: ReturnValue in buffer | semmle.label | [summary] to write: ReturnValue in buffer |
|
||||
@@ -342,59 +262,6 @@ nodes
|
||||
| asio_streams.cpp:100:64:100:71 | *send_str | semmle.label | *send_str |
|
||||
| asio_streams.cpp:101:7:101:17 | send_buffer | semmle.label | send_buffer |
|
||||
| asio_streams.cpp:103:29:103:39 | *send_buffer | semmle.label | *send_buffer |
|
||||
| azure.cpp:62:10:62:14 | [summary param] this in Value | semmle.label | [summary param] this in Value |
|
||||
| azure.cpp:62:10:62:14 | [summary] to write: ReturnValue[*] in Value | semmle.label | [summary] to write: ReturnValue[*] in Value |
|
||||
| azure.cpp:113:16:113:19 | [summary param] *0 in Read [Return] | semmle.label | [summary param] *0 in Read [Return] |
|
||||
| azure.cpp:113:16:113:19 | [summary param] this in Read | semmle.label | [summary param] this in Read |
|
||||
| azure.cpp:114:16:114:26 | [summary param] *0 in ReadToCount [Return] | semmle.label | [summary param] *0 in ReadToCount [Return] |
|
||||
| azure.cpp:114:16:114:26 | [summary param] this in ReadToCount | semmle.label | [summary param] this in ReadToCount |
|
||||
| azure.cpp:115:30:115:38 | [summary param] this in ReadToEnd | semmle.label | [summary param] this in ReadToEnd |
|
||||
| azure.cpp:115:30:115:38 | [summary] to write: ReturnValue in ReadToEnd [element] | semmle.label | [summary] to write: ReturnValue in ReadToEnd [element] |
|
||||
| azure.cpp:115:30:115:38 | [summary] to write: ReturnValue.Element in ReadToEnd | semmle.label | [summary] to write: ReturnValue.Element in ReadToEnd |
|
||||
| azure.cpp:253:48:253:60 | *call to GetBodyStream | semmle.label | *call to GetBodyStream |
|
||||
| azure.cpp:253:48:253:60 | *call to GetBodyStream | semmle.label | *call to GetBodyStream |
|
||||
| azure.cpp:257:5:257:8 | *resp | semmle.label | *resp |
|
||||
| azure.cpp:257:16:257:21 | Read output argument | semmle.label | Read output argument |
|
||||
| azure.cpp:258:10:258:16 | * ... | semmle.label | * ... |
|
||||
| azure.cpp:262:5:262:8 | *resp | semmle.label | *resp |
|
||||
| azure.cpp:262:23:262:28 | ReadToCount output argument | semmle.label | ReadToCount output argument |
|
||||
| azure.cpp:263:10:263:16 | * ... | semmle.label | * ... |
|
||||
| azure.cpp:266:38:266:41 | *resp | semmle.label | *resp |
|
||||
| azure.cpp:266:44:266:52 | call to ReadToEnd [element] | semmle.label | call to ReadToEnd [element] |
|
||||
| azure.cpp:266:44:266:52 | call to ReadToEnd [element] | semmle.label | call to ReadToEnd [element] |
|
||||
| azure.cpp:267:10:267:12 | vec | semmle.label | vec |
|
||||
| azure.cpp:267:10:267:12 | vec [element] | semmle.label | vec [element] |
|
||||
| azure.cpp:273:62:273:64 | call to GetHeaders | semmle.label | call to GetHeaders |
|
||||
| azure.cpp:273:62:273:64 | call to GetHeaders | semmle.label | call to GetHeaders |
|
||||
| azure.cpp:274:10:274:29 | call to operator[] | semmle.label | call to operator[] |
|
||||
| azure.cpp:274:14:274:29 | call to operator[] | semmle.label | call to operator[] |
|
||||
| azure.cpp:274:14:274:29 | call to operator[] | semmle.label | call to operator[] |
|
||||
| azure.cpp:274:14:274:29 | call to operator[] | semmle.label | call to operator[] |
|
||||
| azure.cpp:277:45:277:47 | call to GetBody | semmle.label | call to GetBody |
|
||||
| azure.cpp:277:45:277:47 | call to GetBody | semmle.label | call to GetBody |
|
||||
| azure.cpp:278:10:278:13 | body | semmle.label | body |
|
||||
| azure.cpp:278:10:278:13 | body | semmle.label | body |
|
||||
| azure.cpp:278:10:278:13 | body | semmle.label | body |
|
||||
| azure.cpp:281:68:281:84 | *call to ExtractBodyStream | semmle.label | *call to ExtractBodyStream |
|
||||
| azure.cpp:281:68:281:84 | *call to ExtractBodyStream | semmle.label | *call to ExtractBodyStream |
|
||||
| azure.cpp:282:10:282:38 | call to ReadToEnd | semmle.label | call to ReadToEnd |
|
||||
| azure.cpp:282:21:282:23 | *call to get | semmle.label | *call to get |
|
||||
| azure.cpp:282:28:282:36 | call to ReadToEnd [element] | semmle.label | call to ReadToEnd [element] |
|
||||
| azure.cpp:282:28:282:36 | call to ReadToEnd [element] | semmle.label | call to ReadToEnd [element] |
|
||||
| azure.cpp:289:24:289:56 | call to GetHeader | semmle.label | call to GetHeader |
|
||||
| azure.cpp:289:32:289:40 | call to GetHeader | semmle.label | call to GetHeader |
|
||||
| azure.cpp:289:32:289:40 | call to GetHeader | semmle.label | call to GetHeader |
|
||||
| azure.cpp:289:63:289:65 | call to Value | semmle.label | call to Value |
|
||||
| azure.cpp:289:63:289:65 | call to Value | semmle.label | call to Value |
|
||||
| azure.cpp:290:10:290:20 | headerValue | semmle.label | headerValue |
|
||||
| azure.cpp:290:10:290:20 | headerValue | semmle.label | headerValue |
|
||||
| azure.cpp:290:10:290:20 | headerValue | semmle.label | headerValue |
|
||||
| azure.cpp:293:58:293:67 | call to GetHeaders | semmle.label | call to GetHeaders |
|
||||
| azure.cpp:293:58:293:67 | call to GetHeaders | semmle.label | call to GetHeaders |
|
||||
| azure.cpp:294:38:294:53 | call to operator[] | semmle.label | call to operator[] |
|
||||
| azure.cpp:295:10:295:20 | contentType | semmle.label | contentType |
|
||||
| azure.cpp:295:10:295:20 | contentType | semmle.label | contentType |
|
||||
| azure.cpp:295:10:295:20 | contentType | semmle.label | contentType |
|
||||
| test.cpp:4:5:4:17 | [summary param] 0 in ymlStepManual | semmle.label | [summary param] 0 in ymlStepManual |
|
||||
| test.cpp:4:5:4:17 | [summary] to write: ReturnValue in ymlStepManual | semmle.label | [summary] to write: ReturnValue in ymlStepManual |
|
||||
| test.cpp:5:5:5:20 | [summary param] 0 in ymlStepGenerated | semmle.label | [summary param] 0 in ymlStepGenerated |
|
||||
@@ -615,34 +482,8 @@ nodes
|
||||
| windows.cpp:573:27:573:37 | RtlMoveVolatileMemory output argument | semmle.label | RtlMoveVolatileMemory output argument |
|
||||
| windows.cpp:573:40:573:41 | *& ... | semmle.label | *& ... |
|
||||
| windows.cpp:574:10:574:23 | access to array | semmle.label | access to array |
|
||||
| windows.cpp:645:45:645:50 | WinHttpReadData output argument | semmle.label | WinHttpReadData output argument |
|
||||
| windows.cpp:647:10:647:16 | * ... | semmle.label | * ... |
|
||||
| windows.cpp:652:48:652:53 | WinHttpReadDataEx output argument | semmle.label | WinHttpReadDataEx output argument |
|
||||
| windows.cpp:654:10:654:16 | * ... | semmle.label | * ... |
|
||||
| windows.cpp:659:47:659:52 | WinHttpQueryHeaders output argument | semmle.label | WinHttpQueryHeaders output argument |
|
||||
| windows.cpp:661:10:661:16 | * ... | semmle.label | * ... |
|
||||
| windows.cpp:669:70:669:79 | WinHttpQueryHeadersEx output argument | semmle.label | WinHttpQueryHeadersEx output argument |
|
||||
| windows.cpp:669:82:669:87 | WinHttpQueryHeadersEx output argument | semmle.label | WinHttpQueryHeadersEx output argument |
|
||||
| windows.cpp:669:105:669:112 | WinHttpQueryHeadersEx output argument | semmle.label | WinHttpQueryHeadersEx output argument |
|
||||
| windows.cpp:671:10:671:16 | * ... | semmle.label | * ... |
|
||||
| windows.cpp:673:10:673:29 | * ... | semmle.label | * ... |
|
||||
| windows.cpp:675:10:675:27 | * ... | semmle.label | * ... |
|
||||
| windows.cpp:714:6:714:20 | [summary param] *0 in WinHttpCrackUrl | semmle.label | [summary param] *0 in WinHttpCrackUrl |
|
||||
| windows.cpp:714:6:714:20 | [summary param] *3 in WinHttpCrackUrl [Return] | semmle.label | [summary param] *3 in WinHttpCrackUrl [Return] |
|
||||
| windows.cpp:728:5:728:28 | ... = ... | semmle.label | ... = ... |
|
||||
| windows.cpp:728:12:728:28 | call to source | semmle.label | call to source |
|
||||
| windows.cpp:729:35:729:35 | *x | semmle.label | *x |
|
||||
| windows.cpp:729:44:729:57 | WinHttpCrackUrl output argument | semmle.label | WinHttpCrackUrl output argument |
|
||||
| windows.cpp:731:10:731:36 | * ... | semmle.label | * ... |
|
||||
| windows.cpp:733:10:733:35 | * ... | semmle.label | * ... |
|
||||
| windows.cpp:735:10:735:37 | * ... | semmle.label | * ... |
|
||||
subpaths
|
||||
| asio_streams.cpp:100:64:100:71 | *send_str | asio_streams.cpp:56:18:56:23 | [summary param] *0 in buffer | asio_streams.cpp:56:18:56:23 | [summary] to write: ReturnValue in buffer | asio_streams.cpp:100:44:100:62 | call to buffer |
|
||||
| azure.cpp:257:5:257:8 | *resp | azure.cpp:113:16:113:19 | [summary param] this in Read | azure.cpp:113:16:113:19 | [summary param] *0 in Read [Return] | azure.cpp:257:16:257:21 | Read output argument |
|
||||
| azure.cpp:262:5:262:8 | *resp | azure.cpp:114:16:114:26 | [summary param] this in ReadToCount | azure.cpp:114:16:114:26 | [summary param] *0 in ReadToCount [Return] | azure.cpp:262:23:262:28 | ReadToCount output argument |
|
||||
| azure.cpp:266:38:266:41 | *resp | azure.cpp:115:30:115:38 | [summary param] this in ReadToEnd | azure.cpp:115:30:115:38 | [summary] to write: ReturnValue in ReadToEnd [element] | azure.cpp:266:44:266:52 | call to ReadToEnd [element] |
|
||||
| azure.cpp:282:21:282:23 | *call to get | azure.cpp:115:30:115:38 | [summary param] this in ReadToEnd | azure.cpp:115:30:115:38 | [summary] to write: ReturnValue in ReadToEnd [element] | azure.cpp:282:28:282:36 | call to ReadToEnd [element] |
|
||||
| azure.cpp:289:24:289:56 | call to GetHeader | azure.cpp:62:10:62:14 | [summary param] this in Value | azure.cpp:62:10:62:14 | [summary] to write: ReturnValue[*] in Value | azure.cpp:289:63:289:65 | call to Value |
|
||||
| test.cpp:17:24:17:24 | x | test.cpp:4:5:4:17 | [summary param] 0 in ymlStepManual | test.cpp:4:5:4:17 | [summary] to write: ReturnValue in ymlStepManual | test.cpp:17:10:17:22 | call to ymlStepManual |
|
||||
| test.cpp:21:27:21:27 | x | test.cpp:5:5:5:20 | [summary param] 0 in ymlStepGenerated | test.cpp:5:5:5:20 | [summary] to write: ReturnValue in ymlStepGenerated | test.cpp:21:10:21:25 | call to ymlStepGenerated |
|
||||
| test.cpp:25:35:25:35 | x | test.cpp:6:5:6:27 | [summary param] 0 in ymlStepManual_with_body | test.cpp:6:5:6:27 | [summary] to write: ReturnValue in ymlStepManual_with_body | test.cpp:25:11:25:33 | call to ymlStepManual_with_body |
|
||||
@@ -657,5 +498,4 @@ subpaths
|
||||
| windows.cpp:563:40:563:50 | *& ... [*Buffer] | windows.cpp:510:6:510:25 | [summary param] *1 in RtlCopyUnicodeString [*Buffer] | windows.cpp:510:6:510:25 | [summary param] *0 in RtlCopyUnicodeString [Return] [*Buffer] | windows.cpp:563:26:563:37 | RtlCopyUnicodeString output argument [*Buffer] |
|
||||
| windows.cpp:568:32:568:33 | *& ... | windows.cpp:515:6:515:18 | [summary param] *1 in RtlMoveMemory | windows.cpp:515:6:515:18 | [summary param] *0 in RtlMoveMemory [Return] | windows.cpp:568:19:568:29 | RtlMoveMemory output argument |
|
||||
| windows.cpp:573:40:573:41 | *& ... | windows.cpp:521:17:521:37 | [summary param] *1 in RtlMoveVolatileMemory | windows.cpp:521:17:521:37 | [summary param] *0 in RtlMoveVolatileMemory [Return] | windows.cpp:573:27:573:37 | RtlMoveVolatileMemory output argument |
|
||||
| windows.cpp:729:35:729:35 | *x | windows.cpp:714:6:714:20 | [summary param] *0 in WinHttpCrackUrl | windows.cpp:714:6:714:20 | [summary param] *3 in WinHttpCrackUrl [Return] | windows.cpp:729:44:729:57 | WinHttpCrackUrl output argument |
|
||||
testFailures
|
||||
|
||||
@@ -1,10 +1,4 @@
|
||||
| asio_streams.cpp:87:34:87:44 | read_until output argument | remote |
|
||||
| azure.cpp:253:48:253:60 | *call to GetBodyStream | remote |
|
||||
| azure.cpp:273:62:273:64 | call to GetHeaders | remote |
|
||||
| azure.cpp:277:45:277:47 | call to GetBody | remote |
|
||||
| azure.cpp:281:68:281:84 | *call to ExtractBodyStream | remote |
|
||||
| azure.cpp:289:32:289:40 | call to GetHeader | remote |
|
||||
| azure.cpp:293:58:293:67 | call to GetHeaders | remote |
|
||||
| test.cpp:10:10:10:18 | call to ymlSource | local |
|
||||
| test.cpp:56:8:56:16 | call to ymlSource | local |
|
||||
| test.cpp:94:10:94:18 | call to ymlSource | local |
|
||||
@@ -26,9 +20,3 @@
|
||||
| windows.cpp:318:23:318:37 | *call to MapViewOfFileEx | local |
|
||||
| windows.cpp:325:23:325:42 | *call to MapViewOfFileFromApp | local |
|
||||
| windows.cpp:332:23:332:40 | *call to MapViewOfFileNuma2 | local |
|
||||
| windows.cpp:645:45:645:50 | WinHttpReadData output argument | remote |
|
||||
| windows.cpp:652:48:652:53 | WinHttpReadDataEx output argument | remote |
|
||||
| windows.cpp:659:47:659:52 | WinHttpQueryHeaders output argument | remote |
|
||||
| windows.cpp:669:70:669:79 | WinHttpQueryHeadersEx output argument | remote |
|
||||
| windows.cpp:669:82:669:87 | WinHttpQueryHeadersEx output argument | remote |
|
||||
| windows.cpp:669:105:669:112 | WinHttpQueryHeadersEx output argument | remote |
|
||||
|
||||
@@ -1,12 +1,6 @@
|
||||
| asio_streams.cpp:100:64:100:71 | *send_str | asio_streams.cpp:100:44:100:62 | call to buffer |
|
||||
| azure.cpp:252:79:252:98 | call to string | azure.cpp:252:62:252:99 | call to Url |
|
||||
| azure.cpp:257:5:257:8 | *resp | azure.cpp:257:16:257:21 | Read output argument |
|
||||
| azure.cpp:262:5:262:8 | *resp | azure.cpp:262:23:262:28 | ReadToCount output argument |
|
||||
| azure.cpp:287:79:287:98 | call to string | azure.cpp:287:62:287:99 | call to Url |
|
||||
| azure.cpp:289:24:289:56 | call to GetHeader | azure.cpp:289:63:289:65 | call to Value |
|
||||
| test.cpp:17:24:17:24 | x | test.cpp:17:10:17:22 | call to ymlStepManual |
|
||||
| test.cpp:21:27:21:27 | x | test.cpp:21:10:21:25 | call to ymlStepGenerated |
|
||||
| test.cpp:25:35:25:35 | x | test.cpp:25:11:25:33 | call to ymlStepManual_with_body |
|
||||
| test.cpp:28:35:28:35 | 0 | test.cpp:28:11:28:33 | call to ymlStepManual_with_body |
|
||||
| windows.cpp:27:36:27:38 | *cmd | windows.cpp:27:17:27:34 | **call to CommandLineToArgvA |
|
||||
| windows.cpp:729:35:729:35 | *x | windows.cpp:729:44:729:57 | WinHttpCrackUrl output argument |
|
||||
|
||||
@@ -5586,6 +5586,3 @@
|
||||
| Unrecognized output specification "Field[***hEvent]" in summary model. |
|
||||
| Unrecognized output specification "Parameter[***0]" in summary model. |
|
||||
| Unrecognized output specification "Parameter[****0]" in summary model. |
|
||||
| Unrecognized output specification "ReturnValue[*****]" in summary model. |
|
||||
| Unrecognized output specification "ReturnValue[****]" in summary model. |
|
||||
| Unrecognized output specification "ReturnValue[***]" in summary model. |
|
||||
|
||||
@@ -573,165 +573,4 @@ void test_copy_and_move_memory() {
|
||||
RtlMoveVolatileMemory(dest_buffer, &x, sizeof(x));
|
||||
sink(dest_buffer[0]); // $ ir
|
||||
}
|
||||
}
|
||||
|
||||
using HINTERNET = void*;
|
||||
using ULONGLONG = unsigned long long;
|
||||
using UINT = unsigned int;
|
||||
using PDWORD = DWORD*;
|
||||
using PCSTR = const char*;
|
||||
typedef union _WINHTTP_HEADER_NAME {
|
||||
PCWSTR pwszName;
|
||||
PCSTR pszName;
|
||||
} WINHTTP_HEADER_NAME, *PWINHTTP_HEADER_NAME;
|
||||
typedef struct _WINHTTP_EXTENDED_HEADER {
|
||||
union {
|
||||
PCWSTR pwszName;
|
||||
PCSTR pszName;
|
||||
};
|
||||
union {
|
||||
PCWSTR pwszValue;
|
||||
PCSTR pszValue;
|
||||
};
|
||||
} WINHTTP_EXTENDED_HEADER, *PWINHTTP_EXTENDED_HEADER;
|
||||
|
||||
BOOL WinHttpReadData(
|
||||
HINTERNET hRequest,
|
||||
LPVOID lpBuffer,
|
||||
DWORD dwNumberOfBytesToRead,
|
||||
LPDWORD lpdwNumberOfBytesRead
|
||||
);
|
||||
|
||||
DWORD WinHttpReadDataEx(
|
||||
HINTERNET hRequest,
|
||||
LPVOID lpBuffer,
|
||||
DWORD dwNumberOfBytesToRead,
|
||||
LPDWORD lpdwNumberOfBytesRead,
|
||||
ULONGLONG ullFlags,
|
||||
DWORD cbProperty,
|
||||
PVOID pvProperty
|
||||
);
|
||||
|
||||
using LPCWSTR = const wchar_t*;
|
||||
|
||||
BOOL WinHttpQueryHeaders(
|
||||
HINTERNET hRequest,
|
||||
DWORD dwInfoLevel,
|
||||
LPCWSTR pwszName,
|
||||
LPVOID lpBuffer,
|
||||
LPDWORD lpdwBufferLength,
|
||||
LPDWORD lpdwIndex
|
||||
);
|
||||
|
||||
DWORD WinHttpQueryHeadersEx(
|
||||
HINTERNET hRequest,
|
||||
DWORD dwInfoLevel,
|
||||
ULONGLONG ullFlags,
|
||||
UINT uiCodePage,
|
||||
PDWORD pdwIndex,
|
||||
PWINHTTP_HEADER_NAME pHeaderName,
|
||||
PVOID pBuffer,
|
||||
PDWORD pdwBufferLength,
|
||||
PWINHTTP_EXTENDED_HEADER *ppHeaders,
|
||||
PDWORD pdwHeadersCount
|
||||
);
|
||||
|
||||
void sink(PCSTR);
|
||||
|
||||
void test_winhttp(HINTERNET hRequest) {
|
||||
{
|
||||
char buffer[1024];
|
||||
DWORD bytesRead;
|
||||
BOOL result = WinHttpReadData(hRequest, buffer, sizeof(buffer), &bytesRead);
|
||||
sink(buffer);
|
||||
sink(*buffer); // $ ir
|
||||
}
|
||||
{
|
||||
char buffer[1024];
|
||||
DWORD bytesRead;
|
||||
DWORD result = WinHttpReadDataEx(hRequest, buffer, sizeof(buffer), &bytesRead, 0, 0, nullptr);
|
||||
sink(buffer);
|
||||
sink(*buffer); // $ ir
|
||||
}
|
||||
{
|
||||
char buffer[1024];
|
||||
DWORD bufferLength = sizeof(buffer);
|
||||
WinHttpQueryHeaders(hRequest, 0, nullptr, buffer, &bufferLength, nullptr);
|
||||
sink(buffer);
|
||||
sink(*buffer); // $ ir
|
||||
}
|
||||
{
|
||||
char buffer[1024];
|
||||
DWORD bufferLength = sizeof(buffer);
|
||||
PWINHTTP_EXTENDED_HEADER headers;
|
||||
DWORD headersCount;
|
||||
PWINHTTP_HEADER_NAME headerName;
|
||||
DWORD result = WinHttpQueryHeadersEx(hRequest, 0, 0, 0, nullptr, headerName, buffer, &bufferLength, &headers, &headersCount);
|
||||
sink(buffer);
|
||||
sink(*buffer); // $ ir
|
||||
sink(headerName->pszName);
|
||||
sink(*headerName->pszName); // $ ir
|
||||
sink(headers->pszValue);
|
||||
sink(*headers->pszValue); // $ ir
|
||||
}
|
||||
}
|
||||
|
||||
using LPWSTR = wchar_t*;
|
||||
using INTERNET_SCHEME = enum {
|
||||
INTERNET_SCHEME_INVALID = -1,
|
||||
INTERNET_SCHEME_UNKNOWN = 0,
|
||||
INTERNET_SCHEME_HTTP = 1,
|
||||
INTERNET_SCHEME_HTTPS = 2,
|
||||
INTERNET_SCHEME_FTP = 3,
|
||||
INTERNET_SCHEME_FILE = 4,
|
||||
INTERNET_SCHEME_NEWS = 5,
|
||||
INTERNET_SCHEME_MAILTO = 6,
|
||||
INTERNET_SCHEME_SNEWS = 7,
|
||||
INTERNET_SCHEME_SOCKS = 8,
|
||||
INTERNET_SCHEME_WAIS = 9,
|
||||
INTERNET_SCHEME_LAST = 10
|
||||
};
|
||||
using INTERNET_PORT = unsigned short;
|
||||
|
||||
typedef struct _WINHTTP_URL_COMPONENTS {
|
||||
DWORD dwStructSize;
|
||||
LPWSTR lpszScheme;
|
||||
DWORD dwSchemeLength;
|
||||
INTERNET_SCHEME nScheme;
|
||||
LPWSTR lpszHostName;
|
||||
DWORD dwHostNameLength;
|
||||
INTERNET_PORT nPort;
|
||||
LPWSTR lpszUserName;
|
||||
DWORD dwUserNameLength;
|
||||
LPWSTR lpszPassword;
|
||||
DWORD dwPasswordLength;
|
||||
LPWSTR lpszUrlPath;
|
||||
DWORD dwUrlPathLength;
|
||||
LPWSTR lpszExtraInfo;
|
||||
DWORD dwExtraInfoLength;
|
||||
} URL_COMPONENTS, *LPURL_COMPONENTS;
|
||||
|
||||
BOOL WinHttpCrackUrl(
|
||||
LPCWSTR pwszUrl,
|
||||
DWORD dwUrlLength,
|
||||
DWORD dwFlags,
|
||||
LPURL_COMPONENTS lpUrlComponents
|
||||
);
|
||||
|
||||
void sink(LPWSTR);
|
||||
|
||||
void test_winhttp_crack_url() {
|
||||
{
|
||||
URL_COMPONENTS urlComponents;
|
||||
urlComponents.dwStructSize = sizeof(URL_COMPONENTS);
|
||||
wchar_t x[256];
|
||||
x[0] = (wchar_t)source();
|
||||
BOOL result = WinHttpCrackUrl(x, 0, 0, &urlComponents);
|
||||
sink(urlComponents.lpszHostName);
|
||||
sink(*urlComponents.lpszHostName); // $ ir
|
||||
sink(urlComponents.lpszUrlPath);
|
||||
sink(*urlComponents.lpszUrlPath); // $ ir
|
||||
sink(urlComponents.lpszExtraInfo);
|
||||
sink(*urlComponents.lpszExtraInfo); // $ ir
|
||||
}
|
||||
}
|
||||
@@ -15,10 +15,7 @@ predicate instructionGuardChecks(IRGuardCondition gc, Instruction checked, boole
|
||||
module BarrierGuard = DataFlow::InstructionBarrierGuard<instructionGuardChecks/3>;
|
||||
|
||||
predicate indirectBarrierGuard(DataFlow::Node node, string s) {
|
||||
// This any(...) could technically be removed, but it helps us verify that we don't
|
||||
// accidentially change the API of this predicate (for instance, by having
|
||||
// the column be a unit parameter).
|
||||
node = BarrierGuard::getAnIndirectBarrierNode(any(int indirectionIndex)) and
|
||||
node = BarrierGuard::getAnIndirectBarrierNode(_) and
|
||||
if node.isGLValue()
|
||||
then s = "glval<" + node.getType().toString().replaceAll(" ", "") + ">"
|
||||
else s = node.getType().toString().replaceAll(" ", "")
|
||||
|
||||
22
cpp/ql/test/library-tests/ir/address_constant_folding/test.c
Normal file
22
cpp/ql/test/library-tests/ir/address_constant_folding/test.c
Normal file
@@ -0,0 +1,22 @@
|
||||
#define NULL ((void*)0)
|
||||
|
||||
int global_var;
|
||||
|
||||
void test_address_null_comparison(int param_var) {
|
||||
int local_var;
|
||||
|
||||
if (&global_var == NULL) {} // $ VariableAddress=global_var
|
||||
if (&global_var != NULL) {} // $ VariableAddress=global_var
|
||||
if (&global_var) {} // $ VariableAddress=global_var
|
||||
if (!&global_var) {} // $ VariableAddress=global_var
|
||||
|
||||
if (&local_var == NULL) {} // $ VariableAddress=local_var
|
||||
if (&local_var != NULL) {} // $ VariableAddress=local_var
|
||||
if (&local_var) {} // $ VariableAddress=local_var
|
||||
if (!&local_var) {} // $ VariableAddress=local_var
|
||||
|
||||
if (¶m_var == NULL) {} // $ VariableAddress=param_var
|
||||
if (¶m_var != NULL) {} // $ VariableAddress=param_var
|
||||
if (¶m_var) {} // $ VariableAddress=param_var
|
||||
if (!¶m_var) {} // $ VariableAddress=param_var
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
import cpp
|
||||
private import utils.test.InlineExpectationsTest
|
||||
private import semmle.code.cpp.ir.IR
|
||||
|
||||
module VariableAddressTest implements TestSig {
|
||||
string getARelevantTag() { result = "VariableAddress" }
|
||||
|
||||
predicate hasActualResult(Location location, string element, string tag, string value) {
|
||||
exists(VariableAddressInstruction vai |
|
||||
not vai.getAst() instanceof DeclarationEntry and
|
||||
not vai.getAst() instanceof Parameter and
|
||||
tag = "VariableAddress" and
|
||||
value = vai.getAstVariable().getName() and
|
||||
element = vai.toString() and
|
||||
location = vai.getLocation()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
import MakeTest<VariableAddressTest>
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -2,20 +2,8 @@ import cpp
|
||||
import utils.test.InlineExpectationsTest
|
||||
import semmle.code.cpp.rangeanalysis.SimpleRangeAnalysis
|
||||
|
||||
query predicate estimateNrOfBounds(
|
||||
Expr e, float nrOfBounds, float actualNrOfLowerBounds, float actualNrOfUpperBounds
|
||||
) {
|
||||
nrOfBounds = SimpleRangeAnalysisInternal::estimateNrOfBounds(e) and
|
||||
(
|
||||
actualNrOfLowerBounds = SimpleRangeAnalysisInternal::countNrOfLowerBounds(e)
|
||||
or
|
||||
not exists(SimpleRangeAnalysisInternal::countNrOfLowerBounds(e)) and actualNrOfLowerBounds = -1
|
||||
) and
|
||||
(
|
||||
actualNrOfUpperBounds = SimpleRangeAnalysisInternal::countNrOfUpperBounds(e)
|
||||
or
|
||||
not exists(SimpleRangeAnalysisInternal::countNrOfUpperBounds(e)) and actualNrOfUpperBounds = -1
|
||||
)
|
||||
query predicate estimateNrOfBounds(Expr e, float nrOfBounds) {
|
||||
nrOfBounds = SimpleRangeAnalysisInternal::estimateNrOfBounds(e)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -26,14 +14,8 @@ private predicate nonFunctionalNrOfBounds(Expr e) {
|
||||
strictcount(SimpleRangeAnalysisInternal::estimateNrOfBounds(e)) > 1
|
||||
}
|
||||
|
||||
private predicate nrOfBoundsNotEq1(Expr e, int n) {
|
||||
e.getFile().getBaseName() = "test_nr_of_bounds.cpp" and
|
||||
n = count(SimpleRangeAnalysisInternal::estimateNrOfBounds(e)) and
|
||||
n != 1
|
||||
}
|
||||
|
||||
module FunctionalityTest implements TestSig {
|
||||
string getARelevantTag() { result = ["nonFunctionalNrOfBounds", "bounds"] }
|
||||
string getARelevantTag() { result = "nonFunctionalNrOfBounds" }
|
||||
|
||||
predicate hasActualResult(Location location, string element, string tag, string value) {
|
||||
exists(Expr e |
|
||||
@@ -43,14 +25,6 @@ module FunctionalityTest implements TestSig {
|
||||
tag = "nonFunctionalNrOfBounds" and
|
||||
value = ""
|
||||
)
|
||||
or
|
||||
exists(Expr e, int n |
|
||||
nrOfBoundsNotEq1(e, n) and
|
||||
location = e.getLocation() and
|
||||
element = e.toString() and
|
||||
tag = "bounds" and
|
||||
value = n.toString()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -77,77 +77,77 @@
|
||||
| test.c:426:22:426:82 | ... ? ... : ... | 0.13204114 | 0.42186276 | 0.13204114 |
|
||||
| test.c:426:26:426:69 | ... ? ... : ... | 0.42186276 | 0.42186276 | 0.44996679 |
|
||||
| test.c:426:30:426:56 | ... ? ... : ... | 0.42186276 | 0.42186276 | 0.53843358 |
|
||||
| test.c:485:4:659:27 | ... ? ... : ... | 0.0 | 0.0 | 0.0 |
|
||||
| test.c:485:5:487:49 | ... ? ... : ... | 0.0 | 0.0 | 0.0 |
|
||||
| test.c:488:6:570:25 | ... ? ... : ... | 0.0 | 0.0 | 0.0 |
|
||||
| test.c:489:8:507:41 | ... ? ... : ... | 0.0 | 0.0 | 0.0 |
|
||||
| test.c:492:10:496:21 | ... ? ... : ... | 0.0 | 0.0 | 0.0 |
|
||||
| test.c:492:31:492:79 | ... ? ... : ... | 0.0 | 0.0 | 0.0 |
|
||||
| test.c:494:13:496:21 | ... ? ... : ... | 0.0 | 0.0 | 0.0 |
|
||||
| test.c:501:12:506:23 | ... ? ... : ... | 0.0 | 0.0 | 0.0 |
|
||||
| test.c:502:12:502:60 | ... ? ... : ... | 0.0 | 0.0 | 0.0 |
|
||||
| test.c:504:15:506:23 | ... ? ... : ... | 0.0 | 0.0 | 0.0 |
|
||||
| test.c:508:6:527:23 | ... ? ... : ... | 0.0 | 0.0 | 0.0 |
|
||||
| test.c:511:8:515:19 | ... ? ... : ... | 0.0 | 0.0 | 0.0 |
|
||||
| test.c:511:29:511:77 | ... ? ... : ... | 0.0 | 0.0 | 0.0 |
|
||||
| test.c:513:11:515:19 | ... ? ... : ... | 0.0 | 0.0 | 0.0 |
|
||||
| test.c:516:6:516:54 | ... ? ... : ... | 0.0 | 0.0 | 0.0 |
|
||||
| test.c:520:10:524:21 | ... ? ... : ... | 0.0 | 0.0 | 0.0 |
|
||||
| test.c:520:31:520:79 | ... ? ... : ... | 0.0 | 0.0 | 0.0 |
|
||||
| test.c:522:13:524:21 | ... ? ... : ... | 0.0 | 0.0 | 0.0 |
|
||||
| test.c:525:9:527:23 | ... ? ... : ... | 0.0 | 0.0 | 0.0 |
|
||||
| test.c:529:10:548:43 | ... ? ... : ... | 0.0 | 0.0 | 0.0 |
|
||||
| test.c:532:12:537:23 | ... ? ... : ... | 0.0 | 0.0 | 0.0 |
|
||||
| test.c:533:12:533:60 | ... ? ... : ... | 0.0 | 0.0 | 0.0 |
|
||||
| test.c:535:15:537:23 | ... ? ... : ... | 0.0 | 0.0 | 0.0 |
|
||||
| test.c:542:14:547:25 | ... ? ... : ... | 0.0 | 0.0 | 0.0 |
|
||||
| test.c:543:14:543:62 | ... ? ... : ... | 0.0 | 0.0 | 0.0 |
|
||||
| test.c:545:17:547:25 | ... ? ... : ... | 0.0 | 0.0 | 0.0 |
|
||||
| test.c:549:9:570:25 | ... ? ... : ... | 0.0 | 0.0 | 0.0 |
|
||||
| test.c:552:14:557:25 | ... ? ... : ... | 0.0 | 0.0 | 0.0 |
|
||||
| test.c:553:14:553:62 | ... ? ... : ... | 0.0 | 0.0 | 0.0 |
|
||||
| test.c:555:17:557:25 | ... ? ... : ... | 0.0 | 0.0 | 0.0 |
|
||||
| test.c:558:12:558:60 | ... ? ... : ... | 0.0 | 0.0 | 0.0 |
|
||||
| test.c:562:12:567:23 | ... ? ... : ... | 0.0 | 0.0 | 0.0 |
|
||||
| test.c:563:12:563:60 | ... ? ... : ... | 0.0 | 0.0 | 0.0 |
|
||||
| test.c:565:15:567:23 | ... ? ... : ... | 0.0 | 0.0 | 0.0 |
|
||||
| test.c:568:11:570:25 | ... ? ... : ... | 0.0 | 0.0 | 0.0 |
|
||||
| test.c:571:9:573:51 | ... ? ... : ... | 0.0 | 0.0 | 0.0 |
|
||||
| test.c:574:9:659:27 | ... ? ... : ... | 0.0 | 0.0 | 0.0 |
|
||||
| test.c:575:14:594:47 | ... ? ... : ... | 0.0 | 0.0 | 0.0 |
|
||||
| test.c:578:16:583:27 | ... ? ... : ... | 0.0 | 0.0 | 0.0 |
|
||||
| test.c:579:16:579:64 | ... ? ... : ... | 0.0 | 0.0 | 0.0 |
|
||||
| test.c:581:19:583:27 | ... ? ... : ... | 0.0 | 0.0 | 0.0 |
|
||||
| test.c:588:18:593:29 | ... ? ... : ... | 0.0 | 0.0 | 0.0 |
|
||||
| test.c:589:18:589:66 | ... ? ... : ... | 0.0 | 0.0 | 0.0 |
|
||||
| test.c:591:21:593:29 | ... ? ... : ... | 0.0 | 0.0 | 0.0 |
|
||||
| test.c:595:12:616:29 | ... ? ... : ... | 0.0 | 0.0 | 0.0 |
|
||||
| test.c:598:14:603:25 | ... ? ... : ... | 0.0 | 0.0 | 0.0 |
|
||||
| test.c:599:14:599:62 | ... ? ... : ... | 0.0 | 0.0 | 0.0 |
|
||||
| test.c:601:17:603:25 | ... ? ... : ... | 0.0 | 0.0 | 0.0 |
|
||||
| test.c:604:12:604:60 | ... ? ... : ... | 0.0 | 0.0 | 0.0 |
|
||||
| test.c:608:16:613:27 | ... ? ... : ... | 0.0 | 0.0 | 0.0 |
|
||||
| test.c:609:16:609:64 | ... ? ... : ... | 0.0 | 0.0 | 0.0 |
|
||||
| test.c:611:19:613:27 | ... ? ... : ... | 0.0 | 0.0 | 0.0 |
|
||||
| test.c:614:15:616:29 | ... ? ... : ... | 0.0 | 0.0 | 0.0 |
|
||||
| test.c:618:12:637:45 | ... ? ... : ... | 0.0 | 0.0 | 0.0 |
|
||||
| test.c:621:14:626:25 | ... ? ... : ... | 0.0 | 0.0 | 0.0 |
|
||||
| test.c:622:14:622:62 | ... ? ... : ... | 0.0 | 0.0 | 0.0 |
|
||||
| test.c:624:17:626:25 | ... ? ... : ... | 0.0 | 0.0 | 0.0 |
|
||||
| test.c:631:16:636:27 | ... ? ... : ... | 0.0 | 0.0 | 0.0 |
|
||||
| test.c:632:16:632:64 | ... ? ... : ... | 0.0 | 0.0 | 0.0 |
|
||||
| test.c:634:19:636:27 | ... ? ... : ... | 0.0 | 0.0 | 0.0 |
|
||||
| test.c:638:11:659:27 | ... ? ... : ... | 0.0 | 0.0 | 0.0 |
|
||||
| test.c:641:16:646:27 | ... ? ... : ... | 0.0 | 0.0 | 0.0 |
|
||||
| test.c:642:16:642:64 | ... ? ... : ... | 0.0 | 0.0 | 0.0 |
|
||||
| test.c:644:19:646:27 | ... ? ... : ... | 0.0 | 0.0 | 0.0 |
|
||||
| test.c:647:14:647:62 | ... ? ... : ... | 0.0 | 0.0 | 0.0 |
|
||||
| test.c:651:14:656:25 | ... ? ... : ... | 0.0 | 0.0 | 0.0 |
|
||||
| test.c:652:14:652:62 | ... ? ... : ... | 0.0 | 0.0 | 0.0 |
|
||||
| test.c:654:17:656:25 | ... ? ... : ... | 0.0 | 0.0 | 0.0 |
|
||||
| test.c:657:13:659:27 | ... ? ... : ... | 0.0 | 0.0 | 0.0 |
|
||||
| test.c:685:20:685:36 | ... ? ... : ... | 0.0 | 0.0 | 100.0 |
|
||||
| test.c:897:5:897:14 | ... ? ... : ... | 0.0 | 1.0 | 0.0 |
|
||||
| test.c:898:5:898:14 | ... ? ... : ... | 0.0 | 0.0 | 1.0 |
|
||||
| test.c:468:4:642:27 | ... ? ... : ... | 0.0 | 0.0 | 0.0 |
|
||||
| test.c:468:5:470:49 | ... ? ... : ... | 0.0 | 0.0 | 0.0 |
|
||||
| test.c:471:6:553:25 | ... ? ... : ... | 0.0 | 0.0 | 0.0 |
|
||||
| test.c:472:8:490:41 | ... ? ... : ... | 0.0 | 0.0 | 0.0 |
|
||||
| test.c:475:10:479:21 | ... ? ... : ... | 0.0 | 0.0 | 0.0 |
|
||||
| test.c:475:31:475:79 | ... ? ... : ... | 0.0 | 0.0 | 0.0 |
|
||||
| test.c:477:13:479:21 | ... ? ... : ... | 0.0 | 0.0 | 0.0 |
|
||||
| test.c:484:12:489:23 | ... ? ... : ... | 0.0 | 0.0 | 0.0 |
|
||||
| test.c:485:12:485:60 | ... ? ... : ... | 0.0 | 0.0 | 0.0 |
|
||||
| test.c:487:15:489:23 | ... ? ... : ... | 0.0 | 0.0 | 0.0 |
|
||||
| test.c:491:6:510:23 | ... ? ... : ... | 0.0 | 0.0 | 0.0 |
|
||||
| test.c:494:8:498:19 | ... ? ... : ... | 0.0 | 0.0 | 0.0 |
|
||||
| test.c:494:29:494:77 | ... ? ... : ... | 0.0 | 0.0 | 0.0 |
|
||||
| test.c:496:11:498:19 | ... ? ... : ... | 0.0 | 0.0 | 0.0 |
|
||||
| test.c:499:6:499:54 | ... ? ... : ... | 0.0 | 0.0 | 0.0 |
|
||||
| test.c:503:10:507:21 | ... ? ... : ... | 0.0 | 0.0 | 0.0 |
|
||||
| test.c:503:31:503:79 | ... ? ... : ... | 0.0 | 0.0 | 0.0 |
|
||||
| test.c:505:13:507:21 | ... ? ... : ... | 0.0 | 0.0 | 0.0 |
|
||||
| test.c:508:9:510:23 | ... ? ... : ... | 0.0 | 0.0 | 0.0 |
|
||||
| test.c:512:10:531:43 | ... ? ... : ... | 0.0 | 0.0 | 0.0 |
|
||||
| test.c:515:12:520:23 | ... ? ... : ... | 0.0 | 0.0 | 0.0 |
|
||||
| test.c:516:12:516:60 | ... ? ... : ... | 0.0 | 0.0 | 0.0 |
|
||||
| test.c:518:15:520:23 | ... ? ... : ... | 0.0 | 0.0 | 0.0 |
|
||||
| test.c:525:14:530:25 | ... ? ... : ... | 0.0 | 0.0 | 0.0 |
|
||||
| test.c:526:14:526:62 | ... ? ... : ... | 0.0 | 0.0 | 0.0 |
|
||||
| test.c:528:17:530:25 | ... ? ... : ... | 0.0 | 0.0 | 0.0 |
|
||||
| test.c:532:9:553:25 | ... ? ... : ... | 0.0 | 0.0 | 0.0 |
|
||||
| test.c:535:14:540:25 | ... ? ... : ... | 0.0 | 0.0 | 0.0 |
|
||||
| test.c:536:14:536:62 | ... ? ... : ... | 0.0 | 0.0 | 0.0 |
|
||||
| test.c:538:17:540:25 | ... ? ... : ... | 0.0 | 0.0 | 0.0 |
|
||||
| test.c:541:12:541:60 | ... ? ... : ... | 0.0 | 0.0 | 0.0 |
|
||||
| test.c:545:12:550:23 | ... ? ... : ... | 0.0 | 0.0 | 0.0 |
|
||||
| test.c:546:12:546:60 | ... ? ... : ... | 0.0 | 0.0 | 0.0 |
|
||||
| test.c:548:15:550:23 | ... ? ... : ... | 0.0 | 0.0 | 0.0 |
|
||||
| test.c:551:11:553:25 | ... ? ... : ... | 0.0 | 0.0 | 0.0 |
|
||||
| test.c:554:9:556:51 | ... ? ... : ... | 0.0 | 0.0 | 0.0 |
|
||||
| test.c:557:9:642:27 | ... ? ... : ... | 0.0 | 0.0 | 0.0 |
|
||||
| test.c:558:14:577:47 | ... ? ... : ... | 0.0 | 0.0 | 0.0 |
|
||||
| test.c:561:16:566:27 | ... ? ... : ... | 0.0 | 0.0 | 0.0 |
|
||||
| test.c:562:16:562:64 | ... ? ... : ... | 0.0 | 0.0 | 0.0 |
|
||||
| test.c:564:19:566:27 | ... ? ... : ... | 0.0 | 0.0 | 0.0 |
|
||||
| test.c:571:18:576:29 | ... ? ... : ... | 0.0 | 0.0 | 0.0 |
|
||||
| test.c:572:18:572:66 | ... ? ... : ... | 0.0 | 0.0 | 0.0 |
|
||||
| test.c:574:21:576:29 | ... ? ... : ... | 0.0 | 0.0 | 0.0 |
|
||||
| test.c:578:12:599:29 | ... ? ... : ... | 0.0 | 0.0 | 0.0 |
|
||||
| test.c:581:14:586:25 | ... ? ... : ... | 0.0 | 0.0 | 0.0 |
|
||||
| test.c:582:14:582:62 | ... ? ... : ... | 0.0 | 0.0 | 0.0 |
|
||||
| test.c:584:17:586:25 | ... ? ... : ... | 0.0 | 0.0 | 0.0 |
|
||||
| test.c:587:12:587:60 | ... ? ... : ... | 0.0 | 0.0 | 0.0 |
|
||||
| test.c:591:16:596:27 | ... ? ... : ... | 0.0 | 0.0 | 0.0 |
|
||||
| test.c:592:16:592:64 | ... ? ... : ... | 0.0 | 0.0 | 0.0 |
|
||||
| test.c:594:19:596:27 | ... ? ... : ... | 0.0 | 0.0 | 0.0 |
|
||||
| test.c:597:15:599:29 | ... ? ... : ... | 0.0 | 0.0 | 0.0 |
|
||||
| test.c:601:12:620:45 | ... ? ... : ... | 0.0 | 0.0 | 0.0 |
|
||||
| test.c:604:14:609:25 | ... ? ... : ... | 0.0 | 0.0 | 0.0 |
|
||||
| test.c:605:14:605:62 | ... ? ... : ... | 0.0 | 0.0 | 0.0 |
|
||||
| test.c:607:17:609:25 | ... ? ... : ... | 0.0 | 0.0 | 0.0 |
|
||||
| test.c:614:16:619:27 | ... ? ... : ... | 0.0 | 0.0 | 0.0 |
|
||||
| test.c:615:16:615:64 | ... ? ... : ... | 0.0 | 0.0 | 0.0 |
|
||||
| test.c:617:19:619:27 | ... ? ... : ... | 0.0 | 0.0 | 0.0 |
|
||||
| test.c:621:11:642:27 | ... ? ... : ... | 0.0 | 0.0 | 0.0 |
|
||||
| test.c:624:16:629:27 | ... ? ... : ... | 0.0 | 0.0 | 0.0 |
|
||||
| test.c:625:16:625:64 | ... ? ... : ... | 0.0 | 0.0 | 0.0 |
|
||||
| test.c:627:19:629:27 | ... ? ... : ... | 0.0 | 0.0 | 0.0 |
|
||||
| test.c:630:14:630:62 | ... ? ... : ... | 0.0 | 0.0 | 0.0 |
|
||||
| test.c:634:14:639:25 | ... ? ... : ... | 0.0 | 0.0 | 0.0 |
|
||||
| test.c:635:14:635:62 | ... ? ... : ... | 0.0 | 0.0 | 0.0 |
|
||||
| test.c:637:17:639:25 | ... ? ... : ... | 0.0 | 0.0 | 0.0 |
|
||||
| test.c:640:13:642:27 | ... ? ... : ... | 0.0 | 0.0 | 0.0 |
|
||||
| test.c:668:20:668:36 | ... ? ... : ... | 0.0 | 0.0 | 100.0 |
|
||||
| test.c:880:5:880:14 | ... ? ... : ... | 0.0 | 1.0 | 0.0 |
|
||||
| test.c:881:5:881:14 | ... ? ... : ... | 0.0 | 0.0 | 1.0 |
|
||||
| test.cpp:121:3:121:12 | ... ? ... : ... | 0.0 | 1.0 | 0.0 |
|
||||
| test.cpp:122:3:122:12 | ... ? ... : ... | 0.0 | 0.0 | 1.0 |
|
||||
|
||||
@@ -77,77 +77,77 @@
|
||||
| test.c:426:22:426:82 | ... ? ... : ... | 0.53843358 | 0.53843358 | 0.13204114 |
|
||||
| test.c:426:26:426:69 | ... ? ... : ... | 0.53843358 | 0.53843358 | 0.44996679 |
|
||||
| test.c:426:30:426:56 | ... ? ... : ... | 0.53843358 | 0.42186276 | 0.53843358 |
|
||||
| test.c:485:4:659:27 | ... ? ... : ... | 4.294967295E9 | 4.294967295E9 | 4.294967295E9 |
|
||||
| test.c:485:5:487:49 | ... ? ... : ... | 4.294967295E9 | 4.294967295E9 | 4.294967295E9 |
|
||||
| test.c:488:6:570:25 | ... ? ... : ... | 4.294967295E9 | 4.294967295E9 | 4.294967295E9 |
|
||||
| test.c:489:8:507:41 | ... ? ... : ... | 4.294967295E9 | 4.294967295E9 | 4.294967295E9 |
|
||||
| test.c:492:10:496:21 | ... ? ... : ... | 4.294967295E9 | 4.294967295E9 | 4.294967295E9 |
|
||||
| test.c:492:31:492:79 | ... ? ... : ... | 4.294967295E9 | 4.294967295E9 | 4.294967295E9 |
|
||||
| test.c:494:13:496:21 | ... ? ... : ... | 4.294967295E9 | 4.294967295E9 | 4.294967295E9 |
|
||||
| test.c:501:12:506:23 | ... ? ... : ... | 4.294967295E9 | 4.294967295E9 | 4.294967295E9 |
|
||||
| test.c:502:12:502:60 | ... ? ... : ... | 4.294967295E9 | 4.294967295E9 | 4.294967295E9 |
|
||||
| test.c:504:15:506:23 | ... ? ... : ... | 4.294967295E9 | 4.294967295E9 | 4.294967295E9 |
|
||||
| test.c:508:6:527:23 | ... ? ... : ... | 4.294967295E9 | 4.294967295E9 | 4.294967295E9 |
|
||||
| test.c:511:8:515:19 | ... ? ... : ... | 4.294967295E9 | 4.294967295E9 | 4.294967295E9 |
|
||||
| test.c:511:29:511:77 | ... ? ... : ... | 4.294967295E9 | 4.294967295E9 | 4.294967295E9 |
|
||||
| test.c:513:11:515:19 | ... ? ... : ... | 4.294967295E9 | 4.294967295E9 | 4.294967295E9 |
|
||||
| test.c:516:6:516:54 | ... ? ... : ... | 4.294967295E9 | 4.294967295E9 | 4.294967295E9 |
|
||||
| test.c:520:10:524:21 | ... ? ... : ... | 4.294967295E9 | 4.294967295E9 | 4.294967295E9 |
|
||||
| test.c:520:31:520:79 | ... ? ... : ... | 4.294967295E9 | 4.294967295E9 | 4.294967295E9 |
|
||||
| test.c:522:13:524:21 | ... ? ... : ... | 4.294967295E9 | 4.294967295E9 | 4.294967295E9 |
|
||||
| test.c:525:9:527:23 | ... ? ... : ... | 4.294967295E9 | 4.294967295E9 | 4.294967295E9 |
|
||||
| test.c:529:10:548:43 | ... ? ... : ... | 4.294967295E9 | 4.294967295E9 | 4.294967295E9 |
|
||||
| test.c:532:12:537:23 | ... ? ... : ... | 4.294967295E9 | 4.294967295E9 | 4.294967295E9 |
|
||||
| test.c:533:12:533:60 | ... ? ... : ... | 4.294967295E9 | 4.294967295E9 | 4.294967295E9 |
|
||||
| test.c:535:15:537:23 | ... ? ... : ... | 4.294967295E9 | 4.294967295E9 | 4.294967295E9 |
|
||||
| test.c:542:14:547:25 | ... ? ... : ... | 4.294967295E9 | 4.294967295E9 | 4.294967295E9 |
|
||||
| test.c:543:14:543:62 | ... ? ... : ... | 4.294967295E9 | 4.294967295E9 | 4.294967295E9 |
|
||||
| test.c:545:17:547:25 | ... ? ... : ... | 4.294967295E9 | 4.294967295E9 | 4.294967295E9 |
|
||||
| test.c:549:9:570:25 | ... ? ... : ... | 4.294967295E9 | 4.294967295E9 | 4.294967295E9 |
|
||||
| test.c:552:14:557:25 | ... ? ... : ... | 4.294967295E9 | 4.294967295E9 | 4.294967295E9 |
|
||||
| test.c:553:14:553:62 | ... ? ... : ... | 4.294967295E9 | 4.294967295E9 | 4.294967295E9 |
|
||||
| test.c:555:17:557:25 | ... ? ... : ... | 4.294967295E9 | 4.294967295E9 | 4.294967295E9 |
|
||||
| test.c:558:12:558:60 | ... ? ... : ... | 4.294967295E9 | 4.294967295E9 | 4.294967295E9 |
|
||||
| test.c:562:12:567:23 | ... ? ... : ... | 4.294967295E9 | 4.294967295E9 | 4.294967295E9 |
|
||||
| test.c:563:12:563:60 | ... ? ... : ... | 4.294967295E9 | 4.294967295E9 | 4.294967295E9 |
|
||||
| test.c:565:15:567:23 | ... ? ... : ... | 4.294967295E9 | 4.294967295E9 | 4.294967295E9 |
|
||||
| test.c:568:11:570:25 | ... ? ... : ... | 4.294967295E9 | 4.294967295E9 | 4.294967295E9 |
|
||||
| test.c:571:9:573:51 | ... ? ... : ... | 4.294967295E9 | 4.294967295E9 | 4.294967295E9 |
|
||||
| test.c:574:9:659:27 | ... ? ... : ... | 4.294967295E9 | 4.294967295E9 | 4.294967295E9 |
|
||||
| test.c:575:14:594:47 | ... ? ... : ... | 4.294967295E9 | 4.294967295E9 | 4.294967295E9 |
|
||||
| test.c:578:16:583:27 | ... ? ... : ... | 4.294967295E9 | 4.294967295E9 | 4.294967295E9 |
|
||||
| test.c:579:16:579:64 | ... ? ... : ... | 4.294967295E9 | 4.294967295E9 | 4.294967295E9 |
|
||||
| test.c:581:19:583:27 | ... ? ... : ... | 4.294967295E9 | 4.294967295E9 | 4.294967295E9 |
|
||||
| test.c:588:18:593:29 | ... ? ... : ... | 4.294967295E9 | 4.294967295E9 | 4.294967295E9 |
|
||||
| test.c:589:18:589:66 | ... ? ... : ... | 4.294967295E9 | 4.294967295E9 | 4.294967295E9 |
|
||||
| test.c:591:21:593:29 | ... ? ... : ... | 4.294967295E9 | 4.294967295E9 | 4.294967295E9 |
|
||||
| test.c:595:12:616:29 | ... ? ... : ... | 4.294967295E9 | 4.294967295E9 | 4.294967295E9 |
|
||||
| test.c:598:14:603:25 | ... ? ... : ... | 4.294967295E9 | 4.294967295E9 | 4.294967295E9 |
|
||||
| test.c:599:14:599:62 | ... ? ... : ... | 4.294967295E9 | 4.294967295E9 | 4.294967295E9 |
|
||||
| test.c:601:17:603:25 | ... ? ... : ... | 4.294967295E9 | 4.294967295E9 | 4.294967295E9 |
|
||||
| test.c:604:12:604:60 | ... ? ... : ... | 4.294967295E9 | 4.294967295E9 | 4.294967295E9 |
|
||||
| test.c:608:16:613:27 | ... ? ... : ... | 4.294967295E9 | 4.294967295E9 | 4.294967295E9 |
|
||||
| test.c:609:16:609:64 | ... ? ... : ... | 4.294967295E9 | 4.294967295E9 | 4.294967295E9 |
|
||||
| test.c:611:19:613:27 | ... ? ... : ... | 4.294967295E9 | 4.294967295E9 | 4.294967295E9 |
|
||||
| test.c:614:15:616:29 | ... ? ... : ... | 4.294967295E9 | 4.294967295E9 | 4.294967295E9 |
|
||||
| test.c:618:12:637:45 | ... ? ... : ... | 4.294967295E9 | 4.294967295E9 | 4.294967295E9 |
|
||||
| test.c:621:14:626:25 | ... ? ... : ... | 4.294967295E9 | 4.294967295E9 | 4.294967295E9 |
|
||||
| test.c:622:14:622:62 | ... ? ... : ... | 4.294967295E9 | 4.294967295E9 | 4.294967295E9 |
|
||||
| test.c:624:17:626:25 | ... ? ... : ... | 4.294967295E9 | 4.294967295E9 | 4.294967295E9 |
|
||||
| test.c:631:16:636:27 | ... ? ... : ... | 4.294967295E9 | 4.294967295E9 | 4.294967295E9 |
|
||||
| test.c:632:16:632:64 | ... ? ... : ... | 4.294967295E9 | 4.294967295E9 | 4.294967295E9 |
|
||||
| test.c:634:19:636:27 | ... ? ... : ... | 4.294967295E9 | 4.294967295E9 | 4.294967295E9 |
|
||||
| test.c:638:11:659:27 | ... ? ... : ... | 4.294967295E9 | 4.294967295E9 | 4.294967295E9 |
|
||||
| test.c:641:16:646:27 | ... ? ... : ... | 4.294967295E9 | 4.294967295E9 | 4.294967295E9 |
|
||||
| test.c:642:16:642:64 | ... ? ... : ... | 4.294967295E9 | 4.294967295E9 | 4.294967295E9 |
|
||||
| test.c:644:19:646:27 | ... ? ... : ... | 4.294967295E9 | 4.294967295E9 | 4.294967295E9 |
|
||||
| test.c:647:14:647:62 | ... ? ... : ... | 4.294967295E9 | 4.294967295E9 | 4.294967295E9 |
|
||||
| test.c:651:14:656:25 | ... ? ... : ... | 4.294967295E9 | 4.294967295E9 | 4.294967295E9 |
|
||||
| test.c:652:14:652:62 | ... ? ... : ... | 4.294967295E9 | 4.294967295E9 | 4.294967295E9 |
|
||||
| test.c:654:17:656:25 | ... ? ... : ... | 4.294967295E9 | 4.294967295E9 | 4.294967295E9 |
|
||||
| test.c:657:13:659:27 | ... ? ... : ... | 4.294967295E9 | 4.294967295E9 | 4.294967295E9 |
|
||||
| test.c:685:20:685:36 | ... ? ... : ... | 100.0 | 99.0 | 100.0 |
|
||||
| test.c:897:5:897:14 | ... ? ... : ... | 32767.0 | 32767.0 | 0.0 |
|
||||
| test.c:898:5:898:14 | ... ? ... : ... | 32767.0 | 0.0 | 32767.0 |
|
||||
| test.c:468:4:642:27 | ... ? ... : ... | 4.294967295E9 | 4.294967295E9 | 4.294967295E9 |
|
||||
| test.c:468:5:470:49 | ... ? ... : ... | 4.294967295E9 | 4.294967295E9 | 4.294967295E9 |
|
||||
| test.c:471:6:553:25 | ... ? ... : ... | 4.294967295E9 | 4.294967295E9 | 4.294967295E9 |
|
||||
| test.c:472:8:490:41 | ... ? ... : ... | 4.294967295E9 | 4.294967295E9 | 4.294967295E9 |
|
||||
| test.c:475:10:479:21 | ... ? ... : ... | 4.294967295E9 | 4.294967295E9 | 4.294967295E9 |
|
||||
| test.c:475:31:475:79 | ... ? ... : ... | 4.294967295E9 | 4.294967295E9 | 4.294967295E9 |
|
||||
| test.c:477:13:479:21 | ... ? ... : ... | 4.294967295E9 | 4.294967295E9 | 4.294967295E9 |
|
||||
| test.c:484:12:489:23 | ... ? ... : ... | 4.294967295E9 | 4.294967295E9 | 4.294967295E9 |
|
||||
| test.c:485:12:485:60 | ... ? ... : ... | 4.294967295E9 | 4.294967295E9 | 4.294967295E9 |
|
||||
| test.c:487:15:489:23 | ... ? ... : ... | 4.294967295E9 | 4.294967295E9 | 4.294967295E9 |
|
||||
| test.c:491:6:510:23 | ... ? ... : ... | 4.294967295E9 | 4.294967295E9 | 4.294967295E9 |
|
||||
| test.c:494:8:498:19 | ... ? ... : ... | 4.294967295E9 | 4.294967295E9 | 4.294967295E9 |
|
||||
| test.c:494:29:494:77 | ... ? ... : ... | 4.294967295E9 | 4.294967295E9 | 4.294967295E9 |
|
||||
| test.c:496:11:498:19 | ... ? ... : ... | 4.294967295E9 | 4.294967295E9 | 4.294967295E9 |
|
||||
| test.c:499:6:499:54 | ... ? ... : ... | 4.294967295E9 | 4.294967295E9 | 4.294967295E9 |
|
||||
| test.c:503:10:507:21 | ... ? ... : ... | 4.294967295E9 | 4.294967295E9 | 4.294967295E9 |
|
||||
| test.c:503:31:503:79 | ... ? ... : ... | 4.294967295E9 | 4.294967295E9 | 4.294967295E9 |
|
||||
| test.c:505:13:507:21 | ... ? ... : ... | 4.294967295E9 | 4.294967295E9 | 4.294967295E9 |
|
||||
| test.c:508:9:510:23 | ... ? ... : ... | 4.294967295E9 | 4.294967295E9 | 4.294967295E9 |
|
||||
| test.c:512:10:531:43 | ... ? ... : ... | 4.294967295E9 | 4.294967295E9 | 4.294967295E9 |
|
||||
| test.c:515:12:520:23 | ... ? ... : ... | 4.294967295E9 | 4.294967295E9 | 4.294967295E9 |
|
||||
| test.c:516:12:516:60 | ... ? ... : ... | 4.294967295E9 | 4.294967295E9 | 4.294967295E9 |
|
||||
| test.c:518:15:520:23 | ... ? ... : ... | 4.294967295E9 | 4.294967295E9 | 4.294967295E9 |
|
||||
| test.c:525:14:530:25 | ... ? ... : ... | 4.294967295E9 | 4.294967295E9 | 4.294967295E9 |
|
||||
| test.c:526:14:526:62 | ... ? ... : ... | 4.294967295E9 | 4.294967295E9 | 4.294967295E9 |
|
||||
| test.c:528:17:530:25 | ... ? ... : ... | 4.294967295E9 | 4.294967295E9 | 4.294967295E9 |
|
||||
| test.c:532:9:553:25 | ... ? ... : ... | 4.294967295E9 | 4.294967295E9 | 4.294967295E9 |
|
||||
| test.c:535:14:540:25 | ... ? ... : ... | 4.294967295E9 | 4.294967295E9 | 4.294967295E9 |
|
||||
| test.c:536:14:536:62 | ... ? ... : ... | 4.294967295E9 | 4.294967295E9 | 4.294967295E9 |
|
||||
| test.c:538:17:540:25 | ... ? ... : ... | 4.294967295E9 | 4.294967295E9 | 4.294967295E9 |
|
||||
| test.c:541:12:541:60 | ... ? ... : ... | 4.294967295E9 | 4.294967295E9 | 4.294967295E9 |
|
||||
| test.c:545:12:550:23 | ... ? ... : ... | 4.294967295E9 | 4.294967295E9 | 4.294967295E9 |
|
||||
| test.c:546:12:546:60 | ... ? ... : ... | 4.294967295E9 | 4.294967295E9 | 4.294967295E9 |
|
||||
| test.c:548:15:550:23 | ... ? ... : ... | 4.294967295E9 | 4.294967295E9 | 4.294967295E9 |
|
||||
| test.c:551:11:553:25 | ... ? ... : ... | 4.294967295E9 | 4.294967295E9 | 4.294967295E9 |
|
||||
| test.c:554:9:556:51 | ... ? ... : ... | 4.294967295E9 | 4.294967295E9 | 4.294967295E9 |
|
||||
| test.c:557:9:642:27 | ... ? ... : ... | 4.294967295E9 | 4.294967295E9 | 4.294967295E9 |
|
||||
| test.c:558:14:577:47 | ... ? ... : ... | 4.294967295E9 | 4.294967295E9 | 4.294967295E9 |
|
||||
| test.c:561:16:566:27 | ... ? ... : ... | 4.294967295E9 | 4.294967295E9 | 4.294967295E9 |
|
||||
| test.c:562:16:562:64 | ... ? ... : ... | 4.294967295E9 | 4.294967295E9 | 4.294967295E9 |
|
||||
| test.c:564:19:566:27 | ... ? ... : ... | 4.294967295E9 | 4.294967295E9 | 4.294967295E9 |
|
||||
| test.c:571:18:576:29 | ... ? ... : ... | 4.294967295E9 | 4.294967295E9 | 4.294967295E9 |
|
||||
| test.c:572:18:572:66 | ... ? ... : ... | 4.294967295E9 | 4.294967295E9 | 4.294967295E9 |
|
||||
| test.c:574:21:576:29 | ... ? ... : ... | 4.294967295E9 | 4.294967295E9 | 4.294967295E9 |
|
||||
| test.c:578:12:599:29 | ... ? ... : ... | 4.294967295E9 | 4.294967295E9 | 4.294967295E9 |
|
||||
| test.c:581:14:586:25 | ... ? ... : ... | 4.294967295E9 | 4.294967295E9 | 4.294967295E9 |
|
||||
| test.c:582:14:582:62 | ... ? ... : ... | 4.294967295E9 | 4.294967295E9 | 4.294967295E9 |
|
||||
| test.c:584:17:586:25 | ... ? ... : ... | 4.294967295E9 | 4.294967295E9 | 4.294967295E9 |
|
||||
| test.c:587:12:587:60 | ... ? ... : ... | 4.294967295E9 | 4.294967295E9 | 4.294967295E9 |
|
||||
| test.c:591:16:596:27 | ... ? ... : ... | 4.294967295E9 | 4.294967295E9 | 4.294967295E9 |
|
||||
| test.c:592:16:592:64 | ... ? ... : ... | 4.294967295E9 | 4.294967295E9 | 4.294967295E9 |
|
||||
| test.c:594:19:596:27 | ... ? ... : ... | 4.294967295E9 | 4.294967295E9 | 4.294967295E9 |
|
||||
| test.c:597:15:599:29 | ... ? ... : ... | 4.294967295E9 | 4.294967295E9 | 4.294967295E9 |
|
||||
| test.c:601:12:620:45 | ... ? ... : ... | 4.294967295E9 | 4.294967295E9 | 4.294967295E9 |
|
||||
| test.c:604:14:609:25 | ... ? ... : ... | 4.294967295E9 | 4.294967295E9 | 4.294967295E9 |
|
||||
| test.c:605:14:605:62 | ... ? ... : ... | 4.294967295E9 | 4.294967295E9 | 4.294967295E9 |
|
||||
| test.c:607:17:609:25 | ... ? ... : ... | 4.294967295E9 | 4.294967295E9 | 4.294967295E9 |
|
||||
| test.c:614:16:619:27 | ... ? ... : ... | 4.294967295E9 | 4.294967295E9 | 4.294967295E9 |
|
||||
| test.c:615:16:615:64 | ... ? ... : ... | 4.294967295E9 | 4.294967295E9 | 4.294967295E9 |
|
||||
| test.c:617:19:619:27 | ... ? ... : ... | 4.294967295E9 | 4.294967295E9 | 4.294967295E9 |
|
||||
| test.c:621:11:642:27 | ... ? ... : ... | 4.294967295E9 | 4.294967295E9 | 4.294967295E9 |
|
||||
| test.c:624:16:629:27 | ... ? ... : ... | 4.294967295E9 | 4.294967295E9 | 4.294967295E9 |
|
||||
| test.c:625:16:625:64 | ... ? ... : ... | 4.294967295E9 | 4.294967295E9 | 4.294967295E9 |
|
||||
| test.c:627:19:629:27 | ... ? ... : ... | 4.294967295E9 | 4.294967295E9 | 4.294967295E9 |
|
||||
| test.c:630:14:630:62 | ... ? ... : ... | 4.294967295E9 | 4.294967295E9 | 4.294967295E9 |
|
||||
| test.c:634:14:639:25 | ... ? ... : ... | 4.294967295E9 | 4.294967295E9 | 4.294967295E9 |
|
||||
| test.c:635:14:635:62 | ... ? ... : ... | 4.294967295E9 | 4.294967295E9 | 4.294967295E9 |
|
||||
| test.c:637:17:639:25 | ... ? ... : ... | 4.294967295E9 | 4.294967295E9 | 4.294967295E9 |
|
||||
| test.c:640:13:642:27 | ... ? ... : ... | 4.294967295E9 | 4.294967295E9 | 4.294967295E9 |
|
||||
| test.c:668:20:668:36 | ... ? ... : ... | 100.0 | 99.0 | 100.0 |
|
||||
| test.c:880:5:880:14 | ... ? ... : ... | 32767.0 | 32767.0 | 0.0 |
|
||||
| test.c:881:5:881:14 | ... ? ... : ... | 32767.0 | 0.0 | 32767.0 |
|
||||
| test.cpp:121:3:121:12 | ... ? ... : ... | 32767.0 | 32767.0 | 0.0 |
|
||||
| test.cpp:122:3:122:12 | ... ? ... : ... | 32767.0 | 0.0 | 32767.0 |
|
||||
|
||||
@@ -446,23 +446,6 @@ int repeated_if_statements(unsigned int rhs) {
|
||||
return rhs; // rhs has 6 bounds
|
||||
}
|
||||
|
||||
int repeated_if_else_statements(unsigned int rhs) {
|
||||
// Test how many bounds we estimate for repeated `if`-`else` statements that
|
||||
// guard the same variable.
|
||||
if (rhs < 10) { rhs << 1; } else { rhs << 2; }
|
||||
if (rhs < 11) { rhs << 1; } else { rhs << 2; }
|
||||
if (rhs < 12) { rhs << 1; } else { rhs << 2; }
|
||||
if (rhs < 13) { rhs << 1; } else { rhs << 2; }
|
||||
if (rhs < 14) { rhs << 1; } else { rhs << 2; }
|
||||
if (rhs < 15) { rhs << 1; } else { rhs << 2; }
|
||||
if (rhs < 16) { rhs << 1; } else { rhs << 2; }
|
||||
if (rhs < 17) { rhs << 1; } else { rhs << 2; }
|
||||
if (rhs < 18) { rhs << 1; } else { rhs << 2; }
|
||||
if (rhs < 19) { rhs << 1; } else { rhs << 2; }
|
||||
if (rhs < 20) { rhs << 1; } else { rhs << 2; }
|
||||
return rhs; // rhs has 12 bounds
|
||||
}
|
||||
|
||||
int ne_phi_nodes(int a, int b) {
|
||||
if (a == 17) {
|
||||
if (b == 23) {
|
||||
@@ -989,15 +972,3 @@ void test_overflow() {
|
||||
out(y);
|
||||
}
|
||||
}
|
||||
|
||||
enum MY_ENUM_2 {
|
||||
A = 0x1,
|
||||
B = 0x2,
|
||||
C = 0x4,
|
||||
D = 0x8,
|
||||
E = 0x10
|
||||
};
|
||||
|
||||
void test_enum(enum MY_ENUM_2 e) {
|
||||
out(e);
|
||||
}
|
||||
@@ -1,73 +0,0 @@
|
||||
enum MY_ENUM {
|
||||
A = 0x1,
|
||||
B = 0x2,
|
||||
C = 0x4,
|
||||
D = 0x8,
|
||||
E = 0x10,
|
||||
F = 0x20,
|
||||
G = 0x40,
|
||||
H = 0x80,
|
||||
I = 0x100,
|
||||
J = 0x200,
|
||||
L = 0x400,
|
||||
M = 0x800,
|
||||
N = 0x1000,
|
||||
O = 0x2000,
|
||||
P = 0x4000,
|
||||
Q = 0x8000,
|
||||
R = 0x10000,
|
||||
S = 0x20000,
|
||||
T = 0x40000,
|
||||
U = 0x80000,
|
||||
V = 0x100000,
|
||||
W = 0x200000,
|
||||
X = 0x400000,
|
||||
Y = 0x800000,
|
||||
Z = 0x1000000,
|
||||
AA = 0x2000000,
|
||||
AB = 0x4000000,
|
||||
AC = 0x8000000,
|
||||
AD = 0x10000000,
|
||||
AE = 0x20000000
|
||||
};
|
||||
|
||||
typedef unsigned int MY_ENUM_FLAGS;
|
||||
|
||||
MY_ENUM_FLAGS check_and_subs(MY_ENUM_FLAGS x)
|
||||
{
|
||||
|
||||
#define CHECK_AND_SUB(flag) if ((x & flag) == flag) { x -= flag; }
|
||||
CHECK_AND_SUB(A);
|
||||
CHECK_AND_SUB(B);
|
||||
CHECK_AND_SUB(C);
|
||||
CHECK_AND_SUB(D);
|
||||
CHECK_AND_SUB(E);
|
||||
CHECK_AND_SUB(F);
|
||||
CHECK_AND_SUB(G);
|
||||
CHECK_AND_SUB(H);
|
||||
CHECK_AND_SUB(I);
|
||||
CHECK_AND_SUB(J);
|
||||
CHECK_AND_SUB(L);
|
||||
CHECK_AND_SUB(M);
|
||||
CHECK_AND_SUB(N);
|
||||
CHECK_AND_SUB(O);
|
||||
CHECK_AND_SUB(P);
|
||||
CHECK_AND_SUB(Q);
|
||||
CHECK_AND_SUB(R);
|
||||
CHECK_AND_SUB(S);
|
||||
CHECK_AND_SUB(T);
|
||||
CHECK_AND_SUB(U);
|
||||
CHECK_AND_SUB(V);
|
||||
CHECK_AND_SUB(W);
|
||||
CHECK_AND_SUB(X);
|
||||
CHECK_AND_SUB(Y);
|
||||
CHECK_AND_SUB(Z);
|
||||
CHECK_AND_SUB(AA);
|
||||
CHECK_AND_SUB(AB);
|
||||
CHECK_AND_SUB(AC);
|
||||
CHECK_AND_SUB(AD);
|
||||
CHECK_AND_SUB(AE);
|
||||
#undef CHECK_AND_SUB
|
||||
|
||||
return x;
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,143 +1,15 @@
|
||||
#select
|
||||
| test.cpp:422:2:422:14 | ... += ... | test.cpp:422:2:422:14 | ... += ... | test.cpp:422:2:422:14 | ... += ... | Year field has been modified, but no appropriate check for LeapYear was found. |
|
||||
| test.cpp:440:2:440:11 | ... ++ | test.cpp:440:2:440:11 | ... ++ | test.cpp:440:2:440:11 | ... ++ | Year field has been modified, but no appropriate check for LeapYear was found. |
|
||||
| test.cpp:456:2:456:12 | ... ++ | test.cpp:456:2:456:12 | ... ++ | test.cpp:456:2:456:12 | ... ++ | Year field has been modified, but no appropriate check for LeapYear was found. |
|
||||
| test.cpp:681:2:681:23 | ... += ... | test.cpp:681:2:681:23 | ... += ... | test.cpp:681:2:681:23 | ... += ... | Year field has been modified, but no appropriate check for LeapYear was found. |
|
||||
| test.cpp:813:2:813:40 | ... = ... | test.cpp:813:21:813:40 | ... + ... | test.cpp:813:2:813:40 | ... = ... | Year field has been modified, but no appropriate check for LeapYear was found. |
|
||||
| test.cpp:818:2:818:24 | ... = ... | test.cpp:818:13:818:24 | ... + ... | test.cpp:818:2:818:24 | ... = ... | Year field has been modified, but no appropriate check for LeapYear was found. |
|
||||
| test.cpp:951:3:951:25 | ... = ... | test.cpp:951:14:951:25 | ... + ... | test.cpp:951:3:951:25 | ... = ... | Year field has been modified, but no appropriate check for LeapYear was found. |
|
||||
| test.cpp:969:3:969:12 | ... ++ | test.cpp:969:3:969:12 | ... ++ | test.cpp:969:3:969:12 | ... ++ | Year field has been modified, but no appropriate check for LeapYear was found. |
|
||||
| test.cpp:1031:2:1031:11 | ... ++ | test.cpp:1031:2:1031:11 | ... ++ | test.cpp:1031:2:1031:11 | ... ++ | Year field has been modified, but no appropriate check for LeapYear was found. |
|
||||
| test.cpp:1051:16:1051:23 | increment_arg output argument | test.cpp:1039:2:1039:4 | ... ++ | test.cpp:1051:16:1051:23 | increment_arg output argument | Year field has been modified, but no appropriate check for LeapYear was found. |
|
||||
| test.cpp:1055:27:1055:35 | increment_arg_by_pointer output argument | test.cpp:1043:2:1043:7 | ... ++ | test.cpp:1055:27:1055:35 | increment_arg_by_pointer output argument | Year field has been modified, but no appropriate check for LeapYear was found. |
|
||||
| test.cpp:1109:2:1109:26 | ... = ... | test.cpp:1109:14:1109:26 | ... - ... | test.cpp:1109:2:1109:26 | ... = ... | Year field has been modified, but no appropriate check for LeapYear was found. |
|
||||
| test.cpp:1160:2:1160:19 | ... = ... | test.cpp:1158:2:1158:15 | ... += ... | test.cpp:1160:2:1160:19 | ... = ... | Year field has been modified, but no appropriate check for LeapYear was found. |
|
||||
| test.cpp:1199:2:1199:28 | ... = ... | test.cpp:1199:16:1199:28 | ... + ... | test.cpp:1199:2:1199:28 | ... = ... | Year field has been modified, but no appropriate check for LeapYear was found. |
|
||||
| test.cpp:1214:2:1214:28 | ... = ... | test.cpp:1214:16:1214:28 | ... + ... | test.cpp:1214:2:1214:28 | ... = ... | Year field has been modified, but no appropriate check for LeapYear was found. |
|
||||
| test.cpp:1228:2:1228:28 | ... = ... | test.cpp:1228:16:1228:28 | ... + ... | test.cpp:1228:2:1228:28 | ... = ... | Year field has been modified, but no appropriate check for LeapYear was found. |
|
||||
| test.cpp:1242:2:1242:26 | ... = ... | test.cpp:1242:14:1242:26 | ... + ... | test.cpp:1242:2:1242:26 | ... = ... | Year field has been modified, but no appropriate check for LeapYear was found. |
|
||||
| test.cpp:1256:2:1256:26 | ... = ... | test.cpp:1256:14:1256:26 | ... + ... | test.cpp:1256:2:1256:26 | ... = ... | Year field has been modified, but no appropriate check for LeapYear was found. |
|
||||
| test.cpp:1262:2:1262:28 | ... = ... | test.cpp:1262:16:1262:28 | ... + ... | test.cpp:1262:2:1262:28 | ... = ... | Year field has been modified, but no appropriate check for LeapYear was found. |
|
||||
| test.cpp:1274:2:1274:28 | ... = ... | test.cpp:1274:16:1274:28 | ... + ... | test.cpp:1274:2:1274:28 | ... = ... | Year field has been modified, but no appropriate check for LeapYear was found. |
|
||||
| test.cpp:1287:2:1287:26 | ... = ... | test.cpp:1287:14:1287:26 | ... + ... | test.cpp:1287:2:1287:26 | ... = ... | Year field has been modified, but no appropriate check for LeapYear was found. |
|
||||
| test.cpp:1299:2:1299:26 | ... = ... | test.cpp:1299:14:1299:26 | ... + ... | test.cpp:1299:2:1299:26 | ... = ... | Year field has been modified, but no appropriate check for LeapYear was found. |
|
||||
| test.cpp:1341:2:1341:17 | ... = ... | test.cpp:1432:12:1432:17 | ... + ... | test.cpp:1341:2:1341:17 | ... = ... | Year field has been modified, but no appropriate check for LeapYear was found. |
|
||||
| test.cpp:1341:2:1341:17 | ... = ... | test.cpp:1446:9:1446:16 | ... + ... | test.cpp:1341:2:1341:17 | ... = ... | Year field has been modified, but no appropriate check for LeapYear was found. |
|
||||
| test.cpp:1341:2:1341:17 | ... = ... | test.cpp:1458:9:1458:16 | ... + ... | test.cpp:1341:2:1341:17 | ... = ... | Year field has been modified, but no appropriate check for LeapYear was found. |
|
||||
| test.cpp:1515:2:1515:15 | ... = ... | test.cpp:1512:2:1512:10 | ... += ... | test.cpp:1515:2:1515:15 | ... = ... | Year field has been modified, but no appropriate check for LeapYear was found. |
|
||||
| test.cpp:1545:2:1545:22 | ... += ... | test.cpp:1545:2:1545:22 | ... += ... | test.cpp:1545:2:1545:22 | ... += ... | Year field has been modified, but no appropriate check for LeapYear was found. |
|
||||
| test.cpp:1553:2:1553:22 | ... += ... | test.cpp:1553:2:1553:22 | ... += ... | test.cpp:1553:2:1553:22 | ... += ... | Year field has been modified, but no appropriate check for LeapYear was found. |
|
||||
| test.cpp:1632:2:1632:22 | ... += ... | test.cpp:1632:2:1632:22 | ... += ... | test.cpp:1632:2:1632:22 | ... += ... | Year field has been modified, but no appropriate check for LeapYear was found. |
|
||||
| test.cpp:1644:2:1644:22 | ... += ... | test.cpp:1644:2:1644:22 | ... += ... | test.cpp:1644:2:1644:22 | ... += ... | Year field has been modified, but no appropriate check for LeapYear was found. |
|
||||
| test.cpp:1677:2:1677:22 | ... += ... | test.cpp:1677:2:1677:22 | ... += ... | test.cpp:1677:2:1677:22 | ... += ... | Year field has been modified, but no appropriate check for LeapYear was found. |
|
||||
| test.cpp:1753:2:1753:22 | ... += ... | test.cpp:1753:2:1753:22 | ... += ... | test.cpp:1753:2:1753:22 | ... += ... | Year field has been modified, but no appropriate check for LeapYear was found. |
|
||||
edges
|
||||
| test.cpp:813:21:813:40 | ... + ... | test.cpp:813:2:813:40 | ... = ... | provenance | |
|
||||
| test.cpp:818:13:818:24 | ... + ... | test.cpp:818:2:818:24 | ... = ... | provenance | |
|
||||
| test.cpp:951:14:951:25 | ... + ... | test.cpp:951:3:951:25 | ... = ... | provenance | |
|
||||
| test.cpp:1038:26:1038:26 | *x | test.cpp:1051:16:1051:23 | increment_arg output argument | provenance | |
|
||||
| test.cpp:1039:2:1039:4 | ... ++ | test.cpp:1038:26:1038:26 | *x | provenance | |
|
||||
| test.cpp:1042:37:1042:37 | *x | test.cpp:1055:27:1055:35 | increment_arg_by_pointer output argument | provenance | |
|
||||
| test.cpp:1043:2:1043:7 | ... ++ | test.cpp:1042:37:1042:37 | *x | provenance | |
|
||||
| test.cpp:1109:14:1109:26 | ... - ... | test.cpp:1109:2:1109:26 | ... = ... | provenance | |
|
||||
| test.cpp:1158:2:1158:15 | ... += ... | test.cpp:1160:2:1160:19 | ... = ... | provenance | |
|
||||
| test.cpp:1199:16:1199:28 | ... + ... | test.cpp:1199:2:1199:28 | ... = ... | provenance | |
|
||||
| test.cpp:1214:16:1214:28 | ... + ... | test.cpp:1214:2:1214:28 | ... = ... | provenance | |
|
||||
| test.cpp:1228:16:1228:28 | ... + ... | test.cpp:1228:2:1228:28 | ... = ... | provenance | |
|
||||
| test.cpp:1242:14:1242:26 | ... + ... | test.cpp:1242:2:1242:26 | ... = ... | provenance | |
|
||||
| test.cpp:1256:14:1256:26 | ... + ... | test.cpp:1256:2:1256:26 | ... = ... | provenance | |
|
||||
| test.cpp:1262:16:1262:28 | ... + ... | test.cpp:1262:2:1262:28 | ... = ... | provenance | |
|
||||
| test.cpp:1274:16:1274:28 | ... + ... | test.cpp:1274:2:1274:28 | ... = ... | provenance | |
|
||||
| test.cpp:1287:14:1287:26 | ... + ... | test.cpp:1287:2:1287:26 | ... = ... | provenance | |
|
||||
| test.cpp:1299:14:1299:26 | ... + ... | test.cpp:1299:2:1299:26 | ... = ... | provenance | |
|
||||
| test.cpp:1338:20:1338:23 | year | test.cpp:1341:2:1341:17 | ... = ... | provenance | |
|
||||
| test.cpp:1351:15:1351:22 | ... + ... | test.cpp:1351:3:1351:22 | ... = ... | provenance | |
|
||||
| test.cpp:1356:12:1356:17 | ... + ... | test.cpp:1338:20:1338:23 | year | provenance | |
|
||||
| test.cpp:1365:15:1365:22 | ... + ... | test.cpp:1365:3:1365:22 | ... = ... | provenance | |
|
||||
| test.cpp:1375:3:1375:20 | ... = ... | test.cpp:1377:12:1377:18 | yeartmp | provenance | |
|
||||
| test.cpp:1375:13:1375:20 | ... + ... | test.cpp:1375:3:1375:20 | ... = ... | provenance | |
|
||||
| test.cpp:1377:12:1377:18 | yeartmp | test.cpp:1338:20:1338:23 | year | provenance | |
|
||||
| test.cpp:1420:15:1420:22 | ... + ... | test.cpp:1420:3:1420:22 | ... = ... | provenance | |
|
||||
| test.cpp:1425:12:1425:17 | ... + ... | test.cpp:1338:20:1338:23 | year | provenance | |
|
||||
| test.cpp:1432:12:1432:17 | ... + ... | test.cpp:1338:20:1338:23 | year | provenance | |
|
||||
| test.cpp:1446:2:1446:16 | ... = ... | test.cpp:1450:3:1450:18 | ... = ... | provenance | |
|
||||
| test.cpp:1446:2:1446:16 | ... = ... | test.cpp:1455:12:1455:15 | year | provenance | |
|
||||
| test.cpp:1446:9:1446:16 | ... + ... | test.cpp:1446:2:1446:16 | ... = ... | provenance | |
|
||||
| test.cpp:1455:12:1455:15 | year | test.cpp:1338:20:1338:23 | year | provenance | |
|
||||
| test.cpp:1458:2:1458:16 | ... = ... | test.cpp:1464:12:1464:15 | year | provenance | |
|
||||
| test.cpp:1458:9:1458:16 | ... + ... | test.cpp:1458:2:1458:16 | ... = ... | provenance | |
|
||||
| test.cpp:1464:12:1464:15 | year | test.cpp:1338:20:1338:23 | year | provenance | |
|
||||
| test.cpp:1512:2:1512:10 | ... += ... | test.cpp:1515:2:1515:15 | ... = ... | provenance | |
|
||||
nodes
|
||||
| test.cpp:422:2:422:14 | ... += ... | semmle.label | ... += ... |
|
||||
| test.cpp:440:2:440:11 | ... ++ | semmle.label | ... ++ |
|
||||
| test.cpp:456:2:456:12 | ... ++ | semmle.label | ... ++ |
|
||||
| test.cpp:482:3:482:12 | ... ++ | semmle.label | ... ++ |
|
||||
| test.cpp:681:2:681:23 | ... += ... | semmle.label | ... += ... |
|
||||
| test.cpp:813:2:813:40 | ... = ... | semmle.label | ... = ... |
|
||||
| test.cpp:813:21:813:40 | ... + ... | semmle.label | ... + ... |
|
||||
| test.cpp:818:2:818:24 | ... = ... | semmle.label | ... = ... |
|
||||
| test.cpp:818:13:818:24 | ... + ... | semmle.label | ... + ... |
|
||||
| test.cpp:872:4:872:15 | ... ++ | semmle.label | ... ++ |
|
||||
| test.cpp:951:3:951:25 | ... = ... | semmle.label | ... = ... |
|
||||
| test.cpp:951:14:951:25 | ... + ... | semmle.label | ... + ... |
|
||||
| test.cpp:969:3:969:12 | ... ++ | semmle.label | ... ++ |
|
||||
| test.cpp:1031:2:1031:11 | ... ++ | semmle.label | ... ++ |
|
||||
| test.cpp:1038:26:1038:26 | *x | semmle.label | *x |
|
||||
| test.cpp:1039:2:1039:4 | ... ++ | semmle.label | ... ++ |
|
||||
| test.cpp:1042:37:1042:37 | *x | semmle.label | *x |
|
||||
| test.cpp:1043:2:1043:7 | ... ++ | semmle.label | ... ++ |
|
||||
| test.cpp:1051:16:1051:23 | increment_arg output argument | semmle.label | increment_arg output argument |
|
||||
| test.cpp:1055:27:1055:35 | increment_arg_by_pointer output argument | semmle.label | increment_arg_by_pointer output argument |
|
||||
| test.cpp:1109:2:1109:26 | ... = ... | semmle.label | ... = ... |
|
||||
| test.cpp:1109:14:1109:26 | ... - ... | semmle.label | ... - ... |
|
||||
| test.cpp:1158:2:1158:15 | ... += ... | semmle.label | ... += ... |
|
||||
| test.cpp:1160:2:1160:19 | ... = ... | semmle.label | ... = ... |
|
||||
| test.cpp:1199:2:1199:28 | ... = ... | semmle.label | ... = ... |
|
||||
| test.cpp:1199:16:1199:28 | ... + ... | semmle.label | ... + ... |
|
||||
| test.cpp:1214:2:1214:28 | ... = ... | semmle.label | ... = ... |
|
||||
| test.cpp:1214:16:1214:28 | ... + ... | semmle.label | ... + ... |
|
||||
| test.cpp:1228:2:1228:28 | ... = ... | semmle.label | ... = ... |
|
||||
| test.cpp:1228:16:1228:28 | ... + ... | semmle.label | ... + ... |
|
||||
| test.cpp:1242:2:1242:26 | ... = ... | semmle.label | ... = ... |
|
||||
| test.cpp:1242:14:1242:26 | ... + ... | semmle.label | ... + ... |
|
||||
| test.cpp:1256:2:1256:26 | ... = ... | semmle.label | ... = ... |
|
||||
| test.cpp:1256:14:1256:26 | ... + ... | semmle.label | ... + ... |
|
||||
| test.cpp:1262:2:1262:28 | ... = ... | semmle.label | ... = ... |
|
||||
| test.cpp:1262:16:1262:28 | ... + ... | semmle.label | ... + ... |
|
||||
| test.cpp:1274:2:1274:28 | ... = ... | semmle.label | ... = ... |
|
||||
| test.cpp:1274:16:1274:28 | ... + ... | semmle.label | ... + ... |
|
||||
| test.cpp:1287:2:1287:26 | ... = ... | semmle.label | ... = ... |
|
||||
| test.cpp:1287:14:1287:26 | ... + ... | semmle.label | ... + ... |
|
||||
| test.cpp:1299:2:1299:26 | ... = ... | semmle.label | ... = ... |
|
||||
| test.cpp:1299:14:1299:26 | ... + ... | semmle.label | ... + ... |
|
||||
| test.cpp:1338:20:1338:23 | year | semmle.label | year |
|
||||
| test.cpp:1341:2:1341:17 | ... = ... | semmle.label | ... = ... |
|
||||
| test.cpp:1351:3:1351:22 | ... = ... | semmle.label | ... = ... |
|
||||
| test.cpp:1351:15:1351:22 | ... + ... | semmle.label | ... + ... |
|
||||
| test.cpp:1356:12:1356:17 | ... + ... | semmle.label | ... + ... |
|
||||
| test.cpp:1365:3:1365:22 | ... = ... | semmle.label | ... = ... |
|
||||
| test.cpp:1365:15:1365:22 | ... + ... | semmle.label | ... + ... |
|
||||
| test.cpp:1375:3:1375:20 | ... = ... | semmle.label | ... = ... |
|
||||
| test.cpp:1375:13:1375:20 | ... + ... | semmle.label | ... + ... |
|
||||
| test.cpp:1377:12:1377:18 | yeartmp | semmle.label | yeartmp |
|
||||
| test.cpp:1420:3:1420:22 | ... = ... | semmle.label | ... = ... |
|
||||
| test.cpp:1420:15:1420:22 | ... + ... | semmle.label | ... + ... |
|
||||
| test.cpp:1425:12:1425:17 | ... + ... | semmle.label | ... + ... |
|
||||
| test.cpp:1432:12:1432:17 | ... + ... | semmle.label | ... + ... |
|
||||
| test.cpp:1446:2:1446:16 | ... = ... | semmle.label | ... = ... |
|
||||
| test.cpp:1446:9:1446:16 | ... + ... | semmle.label | ... + ... |
|
||||
| test.cpp:1450:3:1450:18 | ... = ... | semmle.label | ... = ... |
|
||||
| test.cpp:1455:12:1455:15 | year | semmle.label | year |
|
||||
| test.cpp:1458:2:1458:16 | ... = ... | semmle.label | ... = ... |
|
||||
| test.cpp:1458:9:1458:16 | ... + ... | semmle.label | ... + ... |
|
||||
| test.cpp:1464:12:1464:15 | year | semmle.label | year |
|
||||
| test.cpp:1512:2:1512:10 | ... += ... | semmle.label | ... += ... |
|
||||
| test.cpp:1515:2:1515:15 | ... = ... | semmle.label | ... = ... |
|
||||
| test.cpp:1545:2:1545:22 | ... += ... | semmle.label | ... += ... |
|
||||
| test.cpp:1553:2:1553:22 | ... += ... | semmle.label | ... += ... |
|
||||
| test.cpp:1632:2:1632:22 | ... += ... | semmle.label | ... += ... |
|
||||
| test.cpp:1644:2:1644:22 | ... += ... | semmle.label | ... += ... |
|
||||
| test.cpp:1677:2:1677:22 | ... += ... | semmle.label | ... += ... |
|
||||
| test.cpp:1753:2:1753:22 | ... += ... | semmle.label | ... += ... |
|
||||
subpaths
|
||||
| test.cpp:314:5:314:9 | wYear | Field $@ on variable $@ has been modified, but no appropriate check for LeapYear was found. | test.cpp:12:7:12:11 | wYear | wYear | test.cpp:309:13:309:14 | st | st |
|
||||
| test.cpp:327:5:327:9 | wYear | Field $@ on variable $@ has been modified, but no appropriate check for LeapYear was found. | test.cpp:12:7:12:11 | wYear | wYear | test.cpp:322:13:322:14 | st | st |
|
||||
| test.cpp:338:6:338:10 | wYear | Field $@ on variable $@ has been modified, but no appropriate check for LeapYear was found. | test.cpp:12:7:12:11 | wYear | wYear | test.cpp:333:62:333:63 | st | st |
|
||||
| test.cpp:484:5:484:9 | wYear | Field $@ on variable $@ has been modified, but no appropriate check for LeapYear was found. | test.cpp:12:7:12:11 | wYear | wYear | test.cpp:480:13:480:14 | st | st |
|
||||
| test.cpp:497:5:497:9 | wYear | Field $@ on variable $@ has been modified, but no appropriate check for LeapYear was found. | test.cpp:12:7:12:11 | wYear | wYear | test.cpp:492:13:492:14 | st | st |
|
||||
| test.cpp:509:5:509:9 | wYear | Field $@ on variable $@ has been modified, but no appropriate check for LeapYear was found. | test.cpp:12:7:12:11 | wYear | wYear | test.cpp:505:13:505:14 | st | st |
|
||||
| test.cpp:606:11:606:17 | tm_year | Field $@ on variable $@ has been modified, but no appropriate check for LeapYear was found. | test.cpp:56:6:56:12 | tm_year | tm_year | test.cpp:602:12:602:19 | timeinfo | timeinfo |
|
||||
| test.cpp:634:11:634:17 | tm_year | Field $@ on variable $@ has been modified, but no appropriate check for LeapYear was found. | test.cpp:56:6:56:12 | tm_year | tm_year | test.cpp:628:12:628:19 | timeinfo | timeinfo |
|
||||
| test.cpp:636:11:636:17 | tm_year | Field $@ on variable $@ has been modified, but no appropriate check for LeapYear was found. | test.cpp:56:6:56:12 | tm_year | tm_year | test.cpp:628:12:628:19 | timeinfo | timeinfo |
|
||||
| test.cpp:640:5:640:9 | wYear | Field $@ on variable $@ has been modified, but no appropriate check for LeapYear was found. | test.cpp:12:7:12:11 | wYear | wYear | test.cpp:629:13:629:14 | st | st |
|
||||
| test.cpp:642:5:642:9 | wYear | Field $@ on variable $@ has been modified, but no appropriate check for LeapYear was found. | test.cpp:12:7:12:11 | wYear | wYear | test.cpp:629:13:629:14 | st | st |
|
||||
| test.cpp:718:5:718:9 | wYear | Field $@ on variable $@ has been modified, but no appropriate check for LeapYear was found. | test.cpp:12:7:12:11 | wYear | wYear | test.cpp:712:13:712:14 | st | st |
|
||||
| test.cpp:731:5:731:9 | wYear | Field $@ on variable $@ has been modified, but no appropriate check for LeapYear was found. | test.cpp:12:7:12:11 | wYear | wYear | test.cpp:725:13:725:14 | st | st |
|
||||
| test.cpp:732:5:732:9 | wYear | Field $@ on variable $@ has been modified, but no appropriate check for LeapYear was found. | test.cpp:12:7:12:11 | wYear | wYear | test.cpp:725:13:725:14 | st | st |
|
||||
| test.cpp:733:5:733:9 | wYear | Field $@ on variable $@ has been modified, but no appropriate check for LeapYear was found. | test.cpp:12:7:12:11 | wYear | wYear | test.cpp:725:13:725:14 | st | st |
|
||||
|
||||
@@ -1,2 +1 @@
|
||||
query: Likely Bugs/Leap Year/UncheckedLeapYearAfterYearModification.ql
|
||||
postprocess: utils/test/InlineExpectationsTestQuery.ql
|
||||
Likely Bugs/Leap Year/UncheckedLeapYearAfterYearModification.ql
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
| test.cpp:425:2:425:21 | call to SystemTimeToFileTime | Return value of $@ function should be verified to check for any error because variable $@ is not guaranteed to be safe. | test.cpp:101:1:101:20 | SystemTimeToFileTime | SystemTimeToFileTime | test.cpp:417:13:417:14 | st | st |
|
||||
| test.cpp:443:2:443:21 | call to SystemTimeToFileTime | Return value of $@ function should be verified to check for any error because variable $@ is not guaranteed to be safe. | test.cpp:101:1:101:20 | SystemTimeToFileTime | SystemTimeToFileTime | test.cpp:435:13:435:14 | st | st |
|
||||
| test.cpp:459:2:459:21 | call to SystemTimeToFileTime | Return value of $@ function should be verified to check for any error because variable $@ is not guaranteed to be safe. | test.cpp:101:1:101:20 | SystemTimeToFileTime | SystemTimeToFileTime | test.cpp:451:62:451:63 | st | st |
|
||||
| test.cpp:953:3:953:22 | call to SystemTimeToFileTime | Return value of $@ function should be verified to check for any error because variable $@ is not guaranteed to be safe. | test.cpp:101:1:101:20 | SystemTimeToFileTime | SystemTimeToFileTime | test.cpp:944:14:944:15 | st | st |
|
||||
| test.cpp:971:3:971:22 | call to SystemTimeToFileTime | Return value of $@ function should be verified to check for any error because variable $@ is not guaranteed to be safe. | test.cpp:101:1:101:20 | SystemTimeToFileTime | SystemTimeToFileTime | test.cpp:962:14:962:15 | st | st |
|
||||
| test.cpp:1035:2:1035:21 | call to SystemTimeToFileTime | Return value of $@ function should be verified to check for any error because variable $@ is not guaranteed to be safe. | test.cpp:101:1:101:20 | SystemTimeToFileTime | SystemTimeToFileTime | test.cpp:1025:13:1025:14 | st | st |
|
||||
| test.cpp:317:2:317:21 | call to SystemTimeToFileTime | Return value of $@ function should be verified to check for any error because variable $@ is not guaranteed to be safe. | test.cpp:63:1:63:20 | SystemTimeToFileTime | SystemTimeToFileTime | test.cpp:309:13:309:14 | st | st |
|
||||
| test.cpp:330:2:330:21 | call to SystemTimeToFileTime | Return value of $@ function should be verified to check for any error because variable $@ is not guaranteed to be safe. | test.cpp:63:1:63:20 | SystemTimeToFileTime | SystemTimeToFileTime | test.cpp:322:13:322:14 | st | st |
|
||||
| test.cpp:341:2:341:21 | call to SystemTimeToFileTime | Return value of $@ function should be verified to check for any error because variable $@ is not guaranteed to be safe. | test.cpp:63:1:63:20 | SystemTimeToFileTime | SystemTimeToFileTime | test.cpp:333:62:333:63 | st | st |
|
||||
| test.cpp:720:2:720:21 | call to SystemTimeToFileTime | Return value of $@ function should be verified to check for any error because variable $@ is not guaranteed to be safe. | test.cpp:63:1:63:20 | SystemTimeToFileTime | SystemTimeToFileTime | test.cpp:712:13:712:14 | st | st |
|
||||
| test.cpp:735:2:735:21 | call to SystemTimeToFileTime | Return value of $@ function should be verified to check for any error because variable $@ is not guaranteed to be safe. | test.cpp:63:1:63:20 | SystemTimeToFileTime | SystemTimeToFileTime | test.cpp:725:13:725:14 | st | st |
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -250,8 +250,3 @@ void* test_strndupa(const char* s, size_t size) {
|
||||
return s2; // BAD
|
||||
}
|
||||
|
||||
int* f_rec(int *p) {
|
||||
int x;
|
||||
int* px = f_rec(&x); // GOOD
|
||||
return p;
|
||||
}
|
||||
|
||||
@@ -44,5 +44,5 @@ NHibernate,3,,,,,,,,,,,,3,,,,,,,,,,
|
||||
Newtonsoft.Json,,,91,,,,,,,,,,,,,,,,,,,73,18
|
||||
ServiceStack,194,,7,27,,,,,75,,,,92,,,,,,,,,7,
|
||||
SourceGenerators,,,5,,,,,,,,,,,,,,,,,,,,5
|
||||
System,59,47,12495,,6,5,12,,,4,1,,31,2,,6,15,17,4,3,,6382,6113
|
||||
System,59,47,12491,,6,5,12,,,4,1,,31,2,,6,15,17,4,3,,6378,6113
|
||||
Windows.Security.Cryptography.Core,1,,,,,,,1,,,,,,,,,,,,,,,
|
||||
|
||||
|
@@ -8,7 +8,7 @@ C# framework & library support
|
||||
|
||||
Framework / library,Package,Flow sources,Taint & value steps,Sinks (total),`CWE-079` :sub:`Cross-site scripting`
|
||||
`ServiceStack <https://servicestack.net/>`_,"``ServiceStack.*``, ``ServiceStack``",,7,194,
|
||||
System,"``System.*``, ``System``",47,12495,59,5
|
||||
System,"``System.*``, ``System``",47,12491,59,5
|
||||
Others,"``Amazon.Lambda.APIGatewayEvents``, ``Amazon.Lambda.Core``, ``Dapper``, ``ILCompiler``, ``ILLink.RoslynAnalyzer``, ``ILLink.Shared``, ``ILLink.Tasks``, ``Internal.IL``, ``Internal.Pgo``, ``Internal.TypeSystem``, ``Microsoft.ApplicationBlocks.Data``, ``Microsoft.AspNetCore.Components``, ``Microsoft.AspNetCore.Http``, ``Microsoft.AspNetCore.Mvc``, ``Microsoft.AspNetCore.WebUtilities``, ``Microsoft.CSharp``, ``Microsoft.Data.SqlClient``, ``Microsoft.Diagnostics.Tools.Pgo``, ``Microsoft.DotNet.Build.Tasks``, ``Microsoft.DotNet.PlatformAbstractions``, ``Microsoft.EntityFrameworkCore``, ``Microsoft.Extensions.Caching.Distributed``, ``Microsoft.Extensions.Caching.Memory``, ``Microsoft.Extensions.Configuration``, ``Microsoft.Extensions.DependencyInjection``, ``Microsoft.Extensions.DependencyModel``, ``Microsoft.Extensions.Diagnostics.Metrics``, ``Microsoft.Extensions.FileProviders``, ``Microsoft.Extensions.FileSystemGlobbing``, ``Microsoft.Extensions.Hosting``, ``Microsoft.Extensions.Http``, ``Microsoft.Extensions.Logging``, ``Microsoft.Extensions.Options``, ``Microsoft.Extensions.Primitives``, ``Microsoft.Interop``, ``Microsoft.JSInterop``, ``Microsoft.NET.Build.Tasks``, ``Microsoft.VisualBasic``, ``Microsoft.Win32``, ``Mono.Linker``, ``MySql.Data.MySqlClient``, ``NHibernate``, ``Newtonsoft.Json``, ``SourceGenerators``, ``Windows.Security.Cryptography.Core``",60,2406,162,4
|
||||
Totals,,107,14908,415,9
|
||||
Totals,,107,14904,415,9
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,3 +0,0 @@
|
||||
description: Remove the relation `extension_receiver_type` and remove the `extension_type` type kind.
|
||||
compatibility: backwards
|
||||
extension_receiver_type.rel: delete
|
||||
@@ -5,7 +5,6 @@ using System.Security.Cryptography.X509Certificates;
|
||||
using Semmle.Util;
|
||||
using Semmle.Util.Logging;
|
||||
using Newtonsoft.Json;
|
||||
using System.Linq;
|
||||
|
||||
namespace Semmle.Extraction.CSharp.DependencyFetching
|
||||
{
|
||||
@@ -38,8 +37,7 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
|
||||
/// </summary>
|
||||
internal X509Certificate2? Certificate { get; private set; }
|
||||
|
||||
internal static DependabotProxy? GetDependabotProxy(
|
||||
ILogger logger, IDiagnosticsWriter diagnosticsWriter, TemporaryDirectory tempWorkingDirectory)
|
||||
internal static DependabotProxy? GetDependabotProxy(ILogger logger, TemporaryDirectory tempWorkingDirectory)
|
||||
{
|
||||
// Setting HTTP(S)_PROXY and SSL_CERT_FILE have no effect on Windows or macOS,
|
||||
// but we would still end up using the Dependabot proxy to check for feed reachability.
|
||||
@@ -114,23 +112,6 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
|
||||
}
|
||||
}
|
||||
|
||||
// Emit a diagnostic for the discovered private registries, so that it is easy
|
||||
// for users to see that they were picked up.
|
||||
if (result.RegistryURLs.Count > 0)
|
||||
{
|
||||
diagnosticsWriter.AddEntry(new DiagnosticMessage(
|
||||
Language.CSharp,
|
||||
"buildless/analysis-using-private-registries",
|
||||
severity: DiagnosticMessage.TspSeverity.Note,
|
||||
visibility: new DiagnosticMessage.TspVisibility(true, true, true),
|
||||
name: "C# extraction used private package registries",
|
||||
markdownMessage: string.Format(
|
||||
"C# was extracted using the following private package registries:\n\n{0}\n",
|
||||
string.Join("\n", result.RegistryURLs.Select(url => string.Format("- `{0}`", url)))
|
||||
)
|
||||
));
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
@@ -106,7 +106,7 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
|
||||
return BuildScript.Success;
|
||||
}).Run(SystemBuildActions.Instance, startCallback, exitCallback);
|
||||
|
||||
dependabotProxy = DependabotProxy.GetDependabotProxy(logger, diagnosticsWriter, tempWorkingDirectory);
|
||||
dependabotProxy = DependabotProxy.GetDependabotProxy(logger, tempWorkingDirectory);
|
||||
|
||||
try
|
||||
{
|
||||
|
||||
@@ -4,7 +4,6 @@ using System.Diagnostics.CodeAnalysis;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using Microsoft.CodeAnalysis;
|
||||
using Semmle.Util;
|
||||
using Semmle.Extraction.CSharp.Entities;
|
||||
|
||||
namespace Semmle.Extraction.CSharp
|
||||
@@ -165,7 +164,6 @@ namespace Semmle.Extraction.CSharp
|
||||
case TypeKind.Enum:
|
||||
case TypeKind.Delegate:
|
||||
case TypeKind.Error:
|
||||
case TypeKind.Extension:
|
||||
var named = (INamedTypeSymbol)type;
|
||||
named.BuildNamedTypeId(cx, trapFile, symbolBeingDefined, constructUnderlyingTupleType);
|
||||
return;
|
||||
@@ -277,20 +275,6 @@ namespace Semmle.Extraction.CSharp
|
||||
public static IEnumerable<IFieldSymbol?> GetTupleElementsMaybeNull(this INamedTypeSymbol type) =>
|
||||
type.TupleElements;
|
||||
|
||||
private static void BuildExtensionTypeId(this INamedTypeSymbol named, Context cx, EscapingTextWriter trapFile)
|
||||
{
|
||||
trapFile.Write("extension(");
|
||||
if (named.ExtensionMarkerName is not null)
|
||||
{
|
||||
trapFile.Write(named.ExtensionMarkerName);
|
||||
}
|
||||
else
|
||||
{
|
||||
trapFile.Write("unknown");
|
||||
}
|
||||
trapFile.Write(")");
|
||||
}
|
||||
|
||||
private static void BuildQualifierAndName(INamedTypeSymbol named, Context cx, EscapingTextWriter trapFile, ISymbol symbolBeingDefined)
|
||||
{
|
||||
if (named.ContainingType is not null)
|
||||
@@ -305,18 +289,8 @@ namespace Semmle.Extraction.CSharp
|
||||
named.ContainingNamespace.BuildNamespace(cx, trapFile);
|
||||
}
|
||||
|
||||
if (named.IsFileLocal)
|
||||
{
|
||||
trapFile.Write(named.MetadataName);
|
||||
}
|
||||
else if (named.IsExtension)
|
||||
{
|
||||
named.BuildExtensionTypeId(cx, trapFile);
|
||||
}
|
||||
else
|
||||
{
|
||||
trapFile.Write(named.Name);
|
||||
}
|
||||
var name = named.IsFileLocal ? named.MetadataName : named.Name;
|
||||
trapFile.Write(name);
|
||||
}
|
||||
|
||||
private static void BuildTupleId(INamedTypeSymbol named, Context cx, EscapingTextWriter trapFile, ISymbol symbolBeingDefined)
|
||||
@@ -417,7 +391,6 @@ namespace Semmle.Extraction.CSharp
|
||||
case TypeKind.Enum:
|
||||
case TypeKind.Delegate:
|
||||
case TypeKind.Error:
|
||||
case TypeKind.Extension:
|
||||
var named = (INamedTypeSymbol)type;
|
||||
named.BuildNamedTypeDisplayName(cx, trapFile, constructUnderlyingTupleType);
|
||||
return;
|
||||
@@ -492,20 +465,6 @@ namespace Semmle.Extraction.CSharp
|
||||
private static void BuildFunctionPointerTypeDisplayName(this IFunctionPointerTypeSymbol funptr, Context cx, TextWriter trapFile) =>
|
||||
BuildFunctionPointerSignature(funptr, trapFile, s => s.BuildDisplayName(cx, trapFile));
|
||||
|
||||
private static void BuildExtensionTypeDisplayName(this INamedTypeSymbol named, Context cx, TextWriter trapFile)
|
||||
{
|
||||
trapFile.Write("extension(");
|
||||
if (named.ExtensionParameter?.Type is ITypeSymbol type)
|
||||
{
|
||||
type.BuildDisplayName(cx, trapFile);
|
||||
}
|
||||
else
|
||||
{
|
||||
trapFile.Write("unknown");
|
||||
}
|
||||
trapFile.Write(")");
|
||||
}
|
||||
|
||||
private static void BuildNamedTypeDisplayName(this INamedTypeSymbol namedType, Context cx, TextWriter trapFile, bool constructUnderlyingTupleType)
|
||||
{
|
||||
if (!constructUnderlyingTupleType && namedType.IsTupleType)
|
||||
@@ -525,12 +484,6 @@ namespace Semmle.Extraction.CSharp
|
||||
return;
|
||||
}
|
||||
|
||||
if (namedType.IsExtension)
|
||||
{
|
||||
namedType.BuildExtensionTypeDisplayName(cx, trapFile);
|
||||
return;
|
||||
}
|
||||
|
||||
if (namedType.IsAnonymousType)
|
||||
{
|
||||
namedType.BuildAnonymousName(cx, trapFile);
|
||||
@@ -643,84 +596,6 @@ namespace Semmle.Extraction.CSharp
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Return true if this method is a compiler-generated extension method.
|
||||
/// </summary>
|
||||
public static bool IsCompilerGeneratedExtensionMethod(this IMethodSymbol method) =>
|
||||
method.TryGetExtensionMethod() is not null;
|
||||
|
||||
/// <summary>
|
||||
/// Returns the extension method corresponding to this compiler-generated extension method, if it exists.
|
||||
/// </summary>
|
||||
public static IMethodSymbol? TryGetExtensionMethod(this IMethodSymbol method)
|
||||
{
|
||||
if (method.IsImplicitlyDeclared && method.ContainingSymbol is INamedTypeSymbol containingType)
|
||||
{
|
||||
// Extension types are declared within the same type as the generated
|
||||
// extension method implementation.
|
||||
var extensions = containingType.GetMembers()
|
||||
.OfType<INamedTypeSymbol>()
|
||||
.Where(t => t.IsExtension);
|
||||
// Find the (possibly unbound) original extension method that maps to this implementation (if any).
|
||||
var unboundDeclaration = extensions.SelectMany(e => e.GetMembers())
|
||||
.OfType<IMethodSymbol>()
|
||||
.FirstOrDefault(m => SymbolEqualityComparer.Default.Equals(m.AssociatedExtensionImplementation, method.ConstructedFrom));
|
||||
|
||||
var isFullyConstructed = method.IsBoundGenericMethod();
|
||||
if (isFullyConstructed && unboundDeclaration?.ContainingType is INamedTypeSymbol extensionType)
|
||||
{
|
||||
try
|
||||
{
|
||||
// Use the type arguments from the constructed extension method to construct the extension type.
|
||||
var arguments = method.TypeArguments.ToArray();
|
||||
var (extensionTypeArguments, extensionMethodArguments) = arguments.SplitAt(extensionType.TypeParameters.Length);
|
||||
|
||||
// Construct the extension type.
|
||||
var boundExtensionType = extensionType.IsUnboundGenericType()
|
||||
? extensionType.Construct(extensionTypeArguments.ToArray())
|
||||
: extensionType;
|
||||
|
||||
// Find the extension method declaration within the constructed extension type.
|
||||
var extensionDeclaration = boundExtensionType.GetMembers()
|
||||
.OfType<IMethodSymbol>()
|
||||
.First(c => SymbolEqualityComparer.Default.Equals(c.OriginalDefinition, unboundDeclaration));
|
||||
|
||||
// If the extension declaration is unbound apply the remaning type arguments and construct it.
|
||||
return extensionDeclaration.IsUnboundGenericMethod()
|
||||
? extensionDeclaration.Construct(extensionMethodArguments.ToArray())
|
||||
: extensionDeclaration;
|
||||
}
|
||||
catch
|
||||
{
|
||||
// If anything goes wrong, fall back to the unbound declaration.
|
||||
return unboundDeclaration;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return unboundDeclaration;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns true if this method is an unbound generic method.
|
||||
/// </summary>
|
||||
public static bool IsUnboundGenericMethod(this IMethodSymbol method) =>
|
||||
method.IsGenericMethod && SymbolEqualityComparer.Default.Equals(method.ConstructedFrom, method);
|
||||
|
||||
/// <summary>
|
||||
/// Returns true if this method is a bound generic method.
|
||||
/// </summary>
|
||||
public static bool IsBoundGenericMethod(this IMethodSymbol method) => method.IsGenericMethod && !method.IsUnboundGenericMethod();
|
||||
|
||||
/// <summary>
|
||||
/// Returns true if this type is an unbound generic type.
|
||||
/// </summary>
|
||||
public static bool IsUnboundGenericType(this INamedTypeSymbol type) =>
|
||||
type.IsGenericType && SymbolEqualityComparer.Default.Equals(type.ConstructedFrom, type);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the base type of `symbol`. Unlike `symbol.BaseType`, this excludes effective base
|
||||
/// types of type parameters as well as `object` base types.
|
||||
@@ -728,15 +603,6 @@ namespace Semmle.Extraction.CSharp
|
||||
public static INamedTypeSymbol? GetNonObjectBaseType(this ITypeSymbol symbol, Context cx) =>
|
||||
symbol is ITypeParameterSymbol || SymbolEqualityComparer.Default.Equals(symbol.BaseType, cx.Compilation.ObjectType) ? null : symbol.BaseType;
|
||||
|
||||
public static IMethodSymbol GetBodyDeclaringSymbol(this IMethodSymbol method) =>
|
||||
method.PartialImplementationPart ?? method;
|
||||
|
||||
public static IPropertySymbol GetBodyDeclaringSymbol(this IPropertySymbol property) =>
|
||||
property.PartialImplementationPart ?? property;
|
||||
|
||||
public static IEventSymbol GetBodyDeclaringSymbol(this IEventSymbol symbol) =>
|
||||
symbol.PartialImplementationPart ?? symbol;
|
||||
|
||||
[return: NotNullIfNotNull(nameof(symbol))]
|
||||
public static IEntity? CreateEntity(this Context cx, ISymbol symbol)
|
||||
{
|
||||
@@ -826,35 +692,5 @@ namespace Semmle.Extraction.CSharp
|
||||
/// </summary>
|
||||
public static IEnumerable<T> ExtractionCandidates<T>(this IEnumerable<T> symbols) where T : ISymbol =>
|
||||
symbols.Where(symbol => symbol.ShouldExtractSymbol());
|
||||
|
||||
/// <summary>
|
||||
/// Returns the parameter kind for this parameter symbol, e.g. `ref`, `out`, `params`, etc.
|
||||
/// </summary>
|
||||
public static Parameter.Kind GetParameterKind(this IParameterSymbol parameter)
|
||||
{
|
||||
switch (parameter.RefKind)
|
||||
{
|
||||
case RefKind.Out:
|
||||
return Parameter.Kind.Out;
|
||||
case RefKind.Ref:
|
||||
return Parameter.Kind.Ref;
|
||||
case RefKind.In:
|
||||
return Parameter.Kind.In;
|
||||
case RefKind.RefReadOnlyParameter:
|
||||
return Parameter.Kind.RefReadOnly;
|
||||
default:
|
||||
if (parameter.IsParams)
|
||||
return Parameter.Kind.Params;
|
||||
|
||||
if (parameter.Ordinal == 0)
|
||||
{
|
||||
if (parameter.ContainingSymbol is IMethodSymbol method && method.IsExtensionMethod)
|
||||
{
|
||||
return Parameter.Kind.This;
|
||||
}
|
||||
}
|
||||
return Parameter.Kind.None;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -70,7 +70,7 @@ namespace Semmle.Extraction.CSharp.Entities
|
||||
|
||||
Overrides(trapFile);
|
||||
|
||||
if (Symbol.FromSource() && !HasBody)
|
||||
if (Symbol.FromSource() && Block is null)
|
||||
{
|
||||
trapFile.compiler_generated(this);
|
||||
}
|
||||
|
||||
@@ -54,6 +54,22 @@ namespace Semmle.Extraction.CSharp.Entities
|
||||
}
|
||||
}
|
||||
|
||||
protected static void WriteLocationToTrap<T1>(Action<T1, Location> writeAction, T1 entity, Location l)
|
||||
{
|
||||
if (l is not EmptyLocation)
|
||||
{
|
||||
writeAction(entity, l);
|
||||
}
|
||||
}
|
||||
|
||||
protected static void WriteLocationsToTrap<T1>(Action<T1, Location> writeAction, T1 entity, IEnumerable<Location> locations)
|
||||
{
|
||||
foreach (var loc in locations)
|
||||
{
|
||||
WriteLocationToTrap(writeAction, entity, loc);
|
||||
}
|
||||
}
|
||||
|
||||
public override bool NeedsPopulation { get; }
|
||||
|
||||
public override int GetHashCode() => Symbol is null ? 0 : Symbol.GetHashCode();
|
||||
|
||||
@@ -9,14 +9,9 @@ namespace Semmle.Extraction.CSharp.Entities
|
||||
{
|
||||
internal abstract class CachedSymbol<T> : CachedEntity<T> where T : class, ISymbol
|
||||
{
|
||||
private readonly Lazy<BlockSyntax?> blockLazy;
|
||||
private readonly Lazy<ExpressionSyntax?> expressionBodyLazy;
|
||||
|
||||
protected CachedSymbol(Context cx, T init)
|
||||
: base(cx, init)
|
||||
{
|
||||
blockLazy = new Lazy<BlockSyntax?>(() => GetBlock(Symbol));
|
||||
expressionBodyLazy = new Lazy<ExpressionSyntax?>(() => GetExpressionBody(Symbol));
|
||||
}
|
||||
|
||||
public virtual Type? ContainingType => Symbol.ContainingType is not null
|
||||
@@ -37,6 +32,32 @@ namespace Semmle.Extraction.CSharp.Entities
|
||||
Attribute.ExtractAttributes(Context, Symbol, this);
|
||||
}
|
||||
|
||||
protected void PopulateNullability(TextWriter trapFile, AnnotatedTypeSymbol type)
|
||||
{
|
||||
var n = NullabilityEntity.Create(Context, Nullability.Create(type));
|
||||
if (!type.HasObliviousNullability())
|
||||
{
|
||||
trapFile.type_nullability(this, n);
|
||||
}
|
||||
}
|
||||
|
||||
protected void PopulateRefKind(TextWriter trapFile, RefKind kind)
|
||||
{
|
||||
switch (kind)
|
||||
{
|
||||
case RefKind.Out:
|
||||
trapFile.type_annotation(this, Kinds.TypeAnnotation.Out);
|
||||
break;
|
||||
case RefKind.Ref:
|
||||
trapFile.type_annotation(this, Kinds.TypeAnnotation.Ref);
|
||||
break;
|
||||
case RefKind.RefReadOnly:
|
||||
case RefKind.RefReadOnlyParameter:
|
||||
trapFile.type_annotation(this, Kinds.TypeAnnotation.ReadonlyRef);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
protected void PopulateScopedKind(TextWriter trapFile, ScopedKind kind)
|
||||
{
|
||||
switch (kind)
|
||||
@@ -92,29 +113,31 @@ namespace Semmle.Extraction.CSharp.Entities
|
||||
Context.BindComments(this, FullLocation);
|
||||
}
|
||||
|
||||
private static BlockSyntax? GetBlock(T symbol)
|
||||
protected virtual T BodyDeclaringSymbol => Symbol;
|
||||
|
||||
public BlockSyntax? Block
|
||||
{
|
||||
return symbol.DeclaringSyntaxReferences
|
||||
get
|
||||
{
|
||||
return BodyDeclaringSymbol.DeclaringSyntaxReferences
|
||||
.SelectMany(r => r.GetSyntax().ChildNodes())
|
||||
.OfType<BlockSyntax>()
|
||||
.FirstOrDefault();
|
||||
}
|
||||
}
|
||||
|
||||
private static ExpressionSyntax? GetExpressionBody(T symbol)
|
||||
public ExpressionSyntax? ExpressionBody
|
||||
{
|
||||
return symbol.DeclaringSyntaxReferences
|
||||
get
|
||||
{
|
||||
return BodyDeclaringSymbol.DeclaringSyntaxReferences
|
||||
.SelectMany(r => r.GetSyntax().ChildNodes())
|
||||
.OfType<ArrowExpressionClauseSyntax>()
|
||||
.Select(arrow => arrow.Expression)
|
||||
.FirstOrDefault();
|
||||
}
|
||||
}
|
||||
|
||||
public BlockSyntax? Block => blockLazy.Value;
|
||||
|
||||
public ExpressionSyntax? ExpressionBody => expressionBodyLazy.Value;
|
||||
|
||||
public bool HasBody => Block is not null || ExpressionBody is not null;
|
||||
|
||||
public virtual bool IsSourceDeclaration => Symbol.IsSourceDeclaration();
|
||||
|
||||
public override bool NeedsPopulation => Context.Defines(Symbol);
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using Microsoft.CodeAnalysis;
|
||||
using Semmle.Extraction.CSharp.Entities;
|
||||
|
||||
namespace Semmle.Extraction.CSharp
|
||||
{
|
||||
@@ -26,7 +24,7 @@ namespace Semmle.Extraction.CSharp
|
||||
trapFile.WriteUnescaped('\"');
|
||||
}
|
||||
|
||||
public abstract Microsoft.CodeAnalysis.Location? ReportingLocation { get; }
|
||||
public abstract Location? ReportingLocation { get; }
|
||||
|
||||
public abstract TrapStackBehaviour TrapStackBehaviour { get; }
|
||||
|
||||
@@ -67,48 +65,6 @@ namespace Semmle.Extraction.CSharp
|
||||
}
|
||||
#endif
|
||||
|
||||
protected void PopulateRefKind(TextWriter trapFile, RefKind kind)
|
||||
{
|
||||
switch (kind)
|
||||
{
|
||||
case RefKind.Out:
|
||||
trapFile.type_annotation(this, Kinds.TypeAnnotation.Out);
|
||||
break;
|
||||
case RefKind.Ref:
|
||||
trapFile.type_annotation(this, Kinds.TypeAnnotation.Ref);
|
||||
break;
|
||||
case RefKind.RefReadOnly:
|
||||
case RefKind.RefReadOnlyParameter:
|
||||
trapFile.type_annotation(this, Kinds.TypeAnnotation.ReadonlyRef);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
protected void PopulateNullability(TextWriter trapFile, AnnotatedTypeSymbol type)
|
||||
{
|
||||
var n = NullabilityEntity.Create(Context, Nullability.Create(type));
|
||||
if (!type.HasObliviousNullability())
|
||||
{
|
||||
trapFile.type_nullability(this, n);
|
||||
}
|
||||
}
|
||||
|
||||
protected static void WriteLocationToTrap<T1>(Action<T1, Entities.Location> writeAction, T1 entity, Entities.Location l)
|
||||
{
|
||||
if (l is not EmptyLocation)
|
||||
{
|
||||
writeAction(entity, l);
|
||||
}
|
||||
}
|
||||
|
||||
protected static void WriteLocationsToTrap<T1>(Action<T1, Entities.Location> writeAction, T1 entity, IEnumerable<Entities.Location> locations)
|
||||
{
|
||||
foreach (var loc in locations)
|
||||
{
|
||||
WriteLocationToTrap(writeAction, entity, loc);
|
||||
}
|
||||
}
|
||||
|
||||
public override string ToString() => Label.ToString();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -42,7 +42,7 @@ namespace Semmle.Extraction.CSharp.Entities
|
||||
return;
|
||||
}
|
||||
|
||||
if (MakeSyntheticBody)
|
||||
if (MakeSynthetic)
|
||||
{
|
||||
// Create a synthetic empty body for primary and default constructors.
|
||||
Statements.SyntheticEmptyBlock.Create(Context, this, 0, Location);
|
||||
@@ -60,7 +60,7 @@ namespace Semmle.Extraction.CSharp.Entities
|
||||
// Do not extract initializers for constructed types.
|
||||
// Extract initializers for constructors with a body, primary constructors
|
||||
// and default constructors for classes and structs declared in source code.
|
||||
if (!HasBody && !MakeSyntheticBody || Context.OnlyScaffold)
|
||||
if (Block is null && ExpressionBody is null && !MakeSynthetic || Context.OnlyScaffold)
|
||||
{
|
||||
return;
|
||||
}
|
||||
@@ -211,7 +211,7 @@ namespace Semmle.Extraction.CSharp.Entities
|
||||
/// </summary>
|
||||
private bool IsBestSourceLocation => ReportingLocation is not null && Context.IsLocationInContext(ReportingLocation);
|
||||
|
||||
private bool MakeSyntheticBody => (IsPrimary || (IsDefault && IsBestSourceLocation)) && !Context.OnlyScaffold;
|
||||
private bool MakeSynthetic => (IsPrimary || (IsDefault && IsBestSourceLocation)) && !Context.OnlyScaffold;
|
||||
|
||||
[return: NotNullIfNotNull(nameof(constructor))]
|
||||
public static new Constructor? Create(Context cx, IMethodSymbol? constructor)
|
||||
|
||||
@@ -30,10 +30,10 @@ namespace Semmle.Extraction.CSharp.Entities
|
||||
var adder = Symbol.AddMethod;
|
||||
var remover = Symbol.RemoveMethod;
|
||||
|
||||
if (adder is not null)
|
||||
if (!(adder is null))
|
||||
Method.Create(Context, adder);
|
||||
|
||||
if (remover is not null)
|
||||
if (!(remover is null))
|
||||
Method.Create(Context, remover);
|
||||
|
||||
PopulateModifiers(trapFile);
|
||||
@@ -72,7 +72,7 @@ namespace Semmle.Extraction.CSharp.Entities
|
||||
}
|
||||
}
|
||||
|
||||
public static Event Create(Context cx, IEventSymbol symbol) => EventFactory.Instance.CreateEntityFromSymbol(cx, symbol.GetBodyDeclaringSymbol());
|
||||
public static Event Create(Context cx, IEventSymbol symbol) => EventFactory.Instance.CreateEntityFromSymbol(cx, symbol);
|
||||
|
||||
private class EventFactory : CachedEntityFactory<IEventSymbol, Event>
|
||||
{
|
||||
|
||||
@@ -13,10 +13,6 @@ namespace Semmle.Extraction.CSharp.Entities
|
||||
this.@event = @event;
|
||||
}
|
||||
|
||||
public override bool NeedsPopulation =>
|
||||
base.NeedsPopulation &&
|
||||
!Symbol.IsPartialDefinition; // Accessors always have an implementing declaration as well.
|
||||
|
||||
/// <summary>
|
||||
/// Gets the event symbol associated with accessor `symbol`, or `null`
|
||||
/// if there is no associated symbol.
|
||||
@@ -59,7 +55,7 @@ namespace Semmle.Extraction.CSharp.Entities
|
||||
|
||||
Overrides(trapFile);
|
||||
|
||||
if (Symbol.FromSource() && !HasBody)
|
||||
if (Symbol.FromSource() && Block is null)
|
||||
{
|
||||
trapFile.compiler_generated(this);
|
||||
}
|
||||
|
||||
@@ -160,9 +160,6 @@ namespace Semmle.Extraction.CSharp.Entities.Expressions
|
||||
case SyntaxKind.ThisExpression:
|
||||
return This.CreateExplicit(info);
|
||||
|
||||
case SyntaxKind.FieldExpression:
|
||||
return PropertyFieldAccess.Create(info);
|
||||
|
||||
case SyntaxKind.AddressOfExpression:
|
||||
return Unary.Create(info.SetKind(ExprKind.ADDRESS_OF));
|
||||
|
||||
|
||||
@@ -24,16 +24,6 @@ namespace Semmle.Extraction.CSharp.Entities.Expressions
|
||||
|
||||
private bool IsExplicitDelegateInvokeCall() => Kind == ExprKind.DELEGATE_INVOCATION && Context.GetModel(Syntax.Expression).GetSymbolInfo(Syntax.Expression).Symbol is IMethodSymbol m && m.MethodKind == MethodKind.DelegateInvoke;
|
||||
|
||||
private bool IsOperatorCall() => Kind == ExprKind.OPERATOR_INVOCATION;
|
||||
|
||||
private bool IsValidMemberAccessKind()
|
||||
{
|
||||
return Kind == ExprKind.METHOD_INVOCATION ||
|
||||
IsEventDelegateCall() ||
|
||||
IsExplicitDelegateInvokeCall() ||
|
||||
IsOperatorCall();
|
||||
}
|
||||
|
||||
protected override void PopulateExpression(TextWriter trapFile)
|
||||
{
|
||||
if (IsNameof(Syntax))
|
||||
@@ -47,7 +37,7 @@ namespace Semmle.Extraction.CSharp.Entities.Expressions
|
||||
var target = TargetSymbol;
|
||||
switch (Syntax.Expression)
|
||||
{
|
||||
case MemberAccessExpressionSyntax memberAccess when IsValidMemberAccessKind():
|
||||
case MemberAccessExpressionSyntax memberAccess when Kind == ExprKind.METHOD_INVOCATION || IsEventDelegateCall() || IsExplicitDelegateInvokeCall():
|
||||
memberName = memberAccess.Name.Identifier.Text;
|
||||
if (Syntax.Expression.Kind() == SyntaxKind.SimpleMemberAccessExpression)
|
||||
// Qualified method call; `x.M()`
|
||||
@@ -123,24 +113,14 @@ namespace Semmle.Extraction.CSharp.Entities.Expressions
|
||||
|
||||
public SymbolInfo SymbolInfo => info.SymbolInfo;
|
||||
|
||||
private static bool IsOperatorLikeCall(ExpressionNodeInfo info)
|
||||
{
|
||||
return info.SymbolInfo.Symbol is IMethodSymbol method &&
|
||||
method.TryGetExtensionMethod()?.MethodKind == MethodKind.UserDefinedOperator;
|
||||
}
|
||||
|
||||
public IMethodSymbol? TargetSymbol
|
||||
{
|
||||
get
|
||||
{
|
||||
var si = SymbolInfo;
|
||||
|
||||
if (si.Symbol is ISymbol symbol)
|
||||
{
|
||||
var method = symbol as IMethodSymbol;
|
||||
// Case for compiler-generated extension methods.
|
||||
return method?.TryGetExtensionMethod() ?? method;
|
||||
}
|
||||
if (si.Symbol is not null)
|
||||
return si.Symbol as IMethodSymbol;
|
||||
|
||||
if (si.CandidateReason == CandidateReason.OverloadResolutionFailure)
|
||||
{
|
||||
@@ -216,25 +196,15 @@ namespace Semmle.Extraction.CSharp.Entities.Expressions
|
||||
|
||||
private static ExprKind GetKind(ExpressionNodeInfo info)
|
||||
{
|
||||
if (IsNameof((InvocationExpressionSyntax)info.Node))
|
||||
{
|
||||
return ExprKind.NAMEOF;
|
||||
}
|
||||
if (IsDelegateLikeCall(info))
|
||||
{
|
||||
return IsDelegateInvokeCall(info)
|
||||
? ExprKind.DELEGATE_INVOCATION
|
||||
: ExprKind.FUNCTION_POINTER_INVOCATION;
|
||||
}
|
||||
if (IsLocalFunctionInvocation(info))
|
||||
{
|
||||
return ExprKind.LOCAL_FUNCTION_INVOCATION;
|
||||
}
|
||||
if (IsOperatorLikeCall(info))
|
||||
{
|
||||
return ExprKind.OPERATOR_INVOCATION;
|
||||
}
|
||||
return ExprKind.METHOD_INVOCATION;
|
||||
return IsNameof((InvocationExpressionSyntax)info.Node)
|
||||
? ExprKind.NAMEOF
|
||||
: IsDelegateLikeCall(info)
|
||||
? IsDelegateInvokeCall(info)
|
||||
? ExprKind.DELEGATE_INVOCATION
|
||||
: ExprKind.FUNCTION_POINTER_INVOCATION
|
||||
: IsLocalFunctionInvocation(info)
|
||||
? ExprKind.LOCAL_FUNCTION_INVOCATION
|
||||
: ExprKind.METHOD_INVOCATION;
|
||||
}
|
||||
|
||||
private static bool IsNameof(InvocationExpressionSyntax syntax)
|
||||
|
||||
@@ -1,28 +0,0 @@
|
||||
using System.IO;
|
||||
using Microsoft.CodeAnalysis;
|
||||
using Microsoft.CodeAnalysis.CSharp.Syntax;
|
||||
using Semmle.Extraction.Kinds;
|
||||
|
||||
namespace Semmle.Extraction.CSharp.Entities.Expressions
|
||||
{
|
||||
internal class PropertyFieldAccess : Expression<FieldExpressionSyntax>
|
||||
{
|
||||
private PropertyFieldAccess(ExpressionNodeInfo info) : base(info.SetKind(ExprKind.FIELD_ACCESS)) { }
|
||||
|
||||
public static Expression Create(ExpressionNodeInfo info) => new PropertyFieldAccess(info).TryPopulate();
|
||||
|
||||
protected override void PopulateExpression(TextWriter trapFile)
|
||||
{
|
||||
var symbolInfo = Context.GetSymbolInfo(Syntax);
|
||||
if (symbolInfo.Symbol is IFieldSymbol field)
|
||||
{
|
||||
var target = PropertyField.Create(Context, field);
|
||||
trapFile.expr_access(this, target);
|
||||
if (!field.IsStatic)
|
||||
{
|
||||
This.CreateImplicit(Context, field.ContainingType, Location, this, -1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -10,7 +10,7 @@ namespace Semmle.Extraction.CSharp.Entities
|
||||
{
|
||||
internal class Field : CachedSymbol<IFieldSymbol>, IExpressionParentEntity
|
||||
{
|
||||
protected Field(Context cx, IFieldSymbol init)
|
||||
private Field(Context cx, IFieldSymbol init)
|
||||
: base(cx, init)
|
||||
{
|
||||
type = new Lazy<Type>(() => Entities.Type.Create(cx, Symbol.Type));
|
||||
|
||||
@@ -1,9 +0,0 @@
|
||||
namespace Semmle.Extraction.CSharp.Entities
|
||||
{
|
||||
/// <summary>
|
||||
/// Marker interface for parameter entities.
|
||||
/// </summary>
|
||||
internal interface IParameter : IEntity
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -20,8 +20,8 @@ namespace Semmle.Extraction.CSharp.Entities
|
||||
var type = Type.Create(Context, Symbol.Type);
|
||||
trapFile.indexers(this, Symbol.GetName(useMetadataName: true), ContainingType!, type.TypeRef, OriginalDefinition);
|
||||
|
||||
var getter = Symbol.GetMethod;
|
||||
var setter = Symbol.SetMethod;
|
||||
var getter = BodyDeclaringSymbol.GetMethod;
|
||||
var setter = BodyDeclaringSymbol.SetMethod;
|
||||
|
||||
if (getter is null && setter is null)
|
||||
Context.ModelError(Symbol, "No indexer accessor defined");
|
||||
@@ -81,7 +81,7 @@ namespace Semmle.Extraction.CSharp.Entities
|
||||
TypeMention.Create(Context, syntax.Type, this, type);
|
||||
}
|
||||
|
||||
public static new Indexer Create(Context cx, IPropertySymbol prop) => IndexerFactory.Instance.CreateEntityFromSymbol(cx, prop.GetBodyDeclaringSymbol());
|
||||
public static new Indexer Create(Context cx, IPropertySymbol prop) => IndexerFactory.Instance.CreateEntityFromSymbol(cx, prop);
|
||||
|
||||
public override void WriteId(EscapingTextWriter trapFile)
|
||||
{
|
||||
|
||||
@@ -14,28 +14,9 @@ namespace Semmle.Extraction.CSharp.Entities
|
||||
protected Method(Context cx, IMethodSymbol init)
|
||||
: base(cx, init) { }
|
||||
|
||||
private SyntheticExtensionParameter? SyntheticParameter { get; set; }
|
||||
|
||||
private int SynthesizeExtensionParameter()
|
||||
{
|
||||
// Synthesize implicit parameter for extension methods declared using extension(...) syntax.
|
||||
if (Symbol.ContainingSymbol is INamedTypeSymbol type &&
|
||||
type.IsExtension && type.ExtensionParameter is IParameterSymbol parameter &&
|
||||
!string.IsNullOrEmpty(parameter.Name) && !Symbol.IsStatic)
|
||||
{
|
||||
var originalSyntheticParam = OriginalDefinition.SyntheticParameter;
|
||||
SyntheticParameter = SyntheticExtensionParameter.Create(Context, this, parameter, originalSyntheticParam);
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
protected void PopulateParameters()
|
||||
{
|
||||
var originalMethod = OriginalDefinition;
|
||||
var positionOffset = SynthesizeExtensionParameter();
|
||||
|
||||
IEnumerable<IParameterSymbol> parameters = Symbol.Parameters;
|
||||
IEnumerable<IParameterSymbol> originalParameters = originalMethod.Symbol.Parameters;
|
||||
|
||||
@@ -43,8 +24,8 @@ namespace Semmle.Extraction.CSharp.Entities
|
||||
{
|
||||
var original = SymbolEqualityComparer.Default.Equals(p.paramSymbol, p.originalParam)
|
||||
? null
|
||||
: Parameter.Create(Context, p.originalParam, originalMethod, null, positionOffset);
|
||||
Parameter.Create(Context, p.paramSymbol, this, original, positionOffset);
|
||||
: Parameter.Create(Context, p.originalParam, originalMethod);
|
||||
Parameter.Create(Context, p.paramSymbol, this, original);
|
||||
}
|
||||
|
||||
if (Symbol.IsVararg)
|
||||
@@ -85,7 +66,7 @@ namespace Semmle.Extraction.CSharp.Entities
|
||||
else
|
||||
Expression.Create(Context, expr!, this, 0);
|
||||
|
||||
NumberOfLines(trapFile, Symbol, this);
|
||||
NumberOfLines(trapFile, BodyDeclaringSymbol, this);
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -321,9 +302,9 @@ namespace Semmle.Extraction.CSharp.Entities
|
||||
/// <summary>
|
||||
/// Whether this method has unbound type parameters.
|
||||
/// </summary>
|
||||
public bool IsUnboundGeneric => Symbol.IsUnboundGenericMethod();
|
||||
public bool IsUnboundGeneric => IsGeneric && SymbolEqualityComparer.Default.Equals(Symbol.ConstructedFrom, Symbol);
|
||||
|
||||
public bool IsBoundGeneric => Symbol.IsBoundGenericMethod();
|
||||
public bool IsBoundGeneric => IsGeneric && !IsUnboundGeneric;
|
||||
|
||||
protected IMethodSymbol ConstructedFromSymbol => Symbol.ConstructedFrom;
|
||||
|
||||
|
||||
@@ -14,18 +14,16 @@ namespace Semmle.Extraction.CSharp.Entities
|
||||
|
||||
public override string Name => Symbol.GetName();
|
||||
|
||||
protected override IMethodSymbol BodyDeclaringSymbol => Symbol.PartialImplementationPart ?? Symbol;
|
||||
|
||||
public IMethodSymbol SourceDeclaration => Symbol.OriginalDefinition;
|
||||
|
||||
public override Microsoft.CodeAnalysis.Location ReportingLocation =>
|
||||
IsCompilerGeneratedDelegate()
|
||||
? Symbol.ContainingType.GetSymbolLocation()
|
||||
: Symbol.GetSymbolLocation();
|
||||
: BodyDeclaringSymbol.GetSymbolLocation();
|
||||
|
||||
public override bool NeedsPopulation =>
|
||||
(base.NeedsPopulation || IsCompilerGeneratedDelegate()) &&
|
||||
// Exclude compiler-generated extension methods. A call to such a method
|
||||
// is replaced by a call to the defining extension method.
|
||||
!Symbol.IsCompilerGeneratedExtensionMethod();
|
||||
public override bool NeedsPopulation => base.NeedsPopulation || IsCompilerGeneratedDelegate();
|
||||
|
||||
public override void Populate(TextWriter trapFile)
|
||||
{
|
||||
@@ -75,7 +73,7 @@ namespace Semmle.Extraction.CSharp.Entities
|
||||
cx.ExtractionContext.Logger.LogWarning("Reduced extension method symbols should not be directly extracted.");
|
||||
}
|
||||
|
||||
return OrdinaryMethodFactory.Instance.CreateEntityFromSymbol(cx, method.GetBodyDeclaringSymbol());
|
||||
return OrdinaryMethodFactory.Instance.CreateEntityFromSymbol(cx, method);
|
||||
}
|
||||
|
||||
private class OrdinaryMethodFactory : CachedEntityFactory<IMethodSymbol, OrdinaryMethod>
|
||||
|
||||
@@ -7,23 +7,16 @@ using Semmle.Extraction.CSharp.Populators;
|
||||
|
||||
namespace Semmle.Extraction.CSharp.Entities
|
||||
{
|
||||
internal class Parameter : CachedSymbol<IParameterSymbol>, IExpressionParentEntity, IParameter
|
||||
internal class Parameter : CachedSymbol<IParameterSymbol>, IExpressionParentEntity
|
||||
{
|
||||
protected IEntity? Parent { get; set; }
|
||||
protected Parameter Original { get; }
|
||||
private int PositionOffset { get; set; }
|
||||
|
||||
private Parameter(Context cx, IParameterSymbol init, IEntity? parent, Parameter? original, int positionOffset)
|
||||
protected Parameter(Context cx, IParameterSymbol init, IEntity? parent, Parameter? original)
|
||||
: base(cx, init)
|
||||
{
|
||||
Parent = parent;
|
||||
Original = original ?? this;
|
||||
PositionOffset = positionOffset;
|
||||
}
|
||||
|
||||
protected Parameter(Context cx, IParameterSymbol init, IEntity? parent, Parameter? original)
|
||||
: this(cx, init, parent, original, 0)
|
||||
{
|
||||
}
|
||||
|
||||
public override Microsoft.CodeAnalysis.Location ReportingLocation => Symbol.GetSymbolLocation();
|
||||
@@ -39,18 +32,46 @@ namespace Semmle.Extraction.CSharp.Entities
|
||||
RefReadOnly = 6
|
||||
}
|
||||
|
||||
protected virtual int Ordinal => Symbol.Ordinal + PositionOffset;
|
||||
protected virtual int Ordinal => Symbol.Ordinal;
|
||||
|
||||
public static Parameter Create(Context cx, IParameterSymbol param, IEntity parent, Parameter? original = null, int positionOffset = 0)
|
||||
private Kind ParamKind
|
||||
{
|
||||
get
|
||||
{
|
||||
switch (Symbol.RefKind)
|
||||
{
|
||||
case RefKind.Out:
|
||||
return Kind.Out;
|
||||
case RefKind.Ref:
|
||||
return Kind.Ref;
|
||||
case RefKind.In:
|
||||
return Kind.In;
|
||||
case RefKind.RefReadOnlyParameter:
|
||||
return Kind.RefReadOnly;
|
||||
default:
|
||||
if (Symbol.IsParams)
|
||||
return Kind.Params;
|
||||
|
||||
if (Ordinal == 0)
|
||||
{
|
||||
if (Symbol.ContainingSymbol is IMethodSymbol method && method.IsExtensionMethod)
|
||||
return Kind.This;
|
||||
}
|
||||
return Kind.None;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static Parameter Create(Context cx, IParameterSymbol param, IEntity parent, Parameter? original = null)
|
||||
{
|
||||
var cachedSymbol = cx.GetPossiblyCachedParameterSymbol(param);
|
||||
return ParameterFactory.Instance.CreateEntity(cx, cachedSymbol, (cachedSymbol, parent, original, positionOffset));
|
||||
return ParameterFactory.Instance.CreateEntity(cx, cachedSymbol, (cachedSymbol, parent, original));
|
||||
}
|
||||
|
||||
public static Parameter Create(Context cx, IParameterSymbol param)
|
||||
{
|
||||
var cachedSymbol = cx.GetPossiblyCachedParameterSymbol(param);
|
||||
return ParameterFactory.Instance.CreateEntity(cx, cachedSymbol, (cachedSymbol, null, null, 0));
|
||||
return ParameterFactory.Instance.CreateEntity(cx, cachedSymbol, (cachedSymbol, null, null));
|
||||
}
|
||||
|
||||
public override void WriteId(EscapingTextWriter trapFile)
|
||||
@@ -58,9 +79,6 @@ namespace Semmle.Extraction.CSharp.Entities
|
||||
if (Parent is null)
|
||||
Parent = Method.Create(Context, Symbol.ContainingSymbol as IMethodSymbol);
|
||||
|
||||
if (Parent is null && Symbol.ContainingSymbol is INamedTypeSymbol type && type.IsExtension)
|
||||
Parent = Type.Create(Context, type);
|
||||
|
||||
if (Parent is null)
|
||||
throw new InternalError(Symbol, "Couldn't get parent of symbol.");
|
||||
|
||||
@@ -95,8 +113,7 @@ namespace Semmle.Extraction.CSharp.Entities
|
||||
Context.ModelError(Symbol, "Inconsistent parameter declaration");
|
||||
|
||||
var type = Type.Create(Context, Symbol.Type);
|
||||
var kind = Symbol.GetParameterKind();
|
||||
trapFile.@params(this, Name, type.TypeRef, Ordinal, kind, Parent!, Original);
|
||||
trapFile.@params(this, Name, type.TypeRef, Ordinal, ParamKind, Parent!, Original);
|
||||
|
||||
if (Context.OnlyScaffold)
|
||||
{
|
||||
@@ -177,11 +194,11 @@ namespace Semmle.Extraction.CSharp.Entities
|
||||
return syntax?.Default;
|
||||
}
|
||||
|
||||
private class ParameterFactory : CachedEntityFactory<(IParameterSymbol, IEntity?, Parameter?, int), Parameter>
|
||||
private class ParameterFactory : CachedEntityFactory<(IParameterSymbol, IEntity?, Parameter?), Parameter>
|
||||
{
|
||||
public static ParameterFactory Instance { get; } = new ParameterFactory();
|
||||
|
||||
public override Parameter Create(Context cx, (IParameterSymbol, IEntity?, Parameter?, int) init) => new Parameter(cx, init.Item1, init.Item2, init.Item3, init.Item4);
|
||||
public override Parameter Create(Context cx, (IParameterSymbol, IEntity?, Parameter?) init) => new Parameter(cx, init.Item1, init.Item2, init.Item3);
|
||||
}
|
||||
|
||||
public override TrapStackBehaviour TrapStackBehaviour => TrapStackBehaviour.OptionalLabel;
|
||||
|
||||
@@ -21,6 +21,10 @@ namespace Semmle.Extraction.CSharp.Entities
|
||||
|
||||
private Type Type => type.Value;
|
||||
|
||||
protected override IPropertySymbol BodyDeclaringSymbol => Symbol.PartialImplementationPart ?? Symbol;
|
||||
|
||||
public override Microsoft.CodeAnalysis.Location? ReportingLocation => BodyDeclaringSymbol.Locations.BestOrDefault();
|
||||
|
||||
public override void WriteId(EscapingTextWriter trapFile)
|
||||
{
|
||||
trapFile.WriteSubId(Type);
|
||||
@@ -42,8 +46,8 @@ namespace Semmle.Extraction.CSharp.Entities
|
||||
var type = Type;
|
||||
trapFile.properties(this, Symbol.GetName(), ContainingType!, type.TypeRef, Create(Context, Symbol.OriginalDefinition));
|
||||
|
||||
var getter = Symbol.GetMethod;
|
||||
var setter = Symbol.SetMethod;
|
||||
var getter = BodyDeclaringSymbol.GetMethod;
|
||||
var setter = BodyDeclaringSymbol.SetMethod;
|
||||
|
||||
if (getter is not null)
|
||||
Method.Create(Context, getter);
|
||||
@@ -128,7 +132,7 @@ namespace Semmle.Extraction.CSharp.Entities
|
||||
{
|
||||
var isIndexer = prop.IsIndexer || prop.Parameters.Any();
|
||||
|
||||
return isIndexer ? Indexer.Create(cx, prop) : PropertyFactory.Instance.CreateEntityFromSymbol(cx, prop.GetBodyDeclaringSymbol());
|
||||
return isIndexer ? Indexer.Create(cx, prop) : PropertyFactory.Instance.CreateEntityFromSymbol(cx, prop);
|
||||
}
|
||||
|
||||
private class PropertyFactory : CachedEntityFactory<IPropertySymbol, Property>
|
||||
|
||||
@@ -1,53 +0,0 @@
|
||||
using System.IO;
|
||||
using Microsoft.CodeAnalysis;
|
||||
using Semmle.Extraction.CSharp.Util;
|
||||
using Semmle.Extraction.Kinds;
|
||||
|
||||
namespace Semmle.Extraction.CSharp.Entities
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents the autogenerated backing field `field` for a property.
|
||||
/// It is only created for properties that use the `field` keyword in their getter or setter, and
|
||||
/// is not created for auto-properties.
|
||||
/// </summary>
|
||||
internal class PropertyField : Field
|
||||
{
|
||||
protected PropertyField(Context cx, IFieldSymbol init)
|
||||
: base(cx, init)
|
||||
{
|
||||
}
|
||||
|
||||
public static new PropertyField Create(Context cx, IFieldSymbol field) => PropertyFieldFactory.Instance.CreateEntity(cx, (field, field.AssociatedSymbol), field);
|
||||
|
||||
public override bool NeedsPopulation => true;
|
||||
|
||||
public override void Populate(TextWriter trapFile)
|
||||
{
|
||||
PopulateNullability(trapFile, Symbol.GetAnnotatedType());
|
||||
|
||||
var unboundFieldKey = PropertyField.Create(Context, Symbol.OriginalDefinition);
|
||||
var name = Symbol.AssociatedSymbol is not null ? $"{Symbol.AssociatedSymbol.GetName()}.field" : Symbol.Name;
|
||||
trapFile.fields(this, VariableKind.None, name, ContainingType!, Type.TypeRef, unboundFieldKey);
|
||||
trapFile.compiler_generated(this);
|
||||
|
||||
PopulateModifiers(trapFile);
|
||||
|
||||
if (Context.OnlyScaffold)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (Context.ExtractLocation(Symbol))
|
||||
{
|
||||
WriteLocationsToTrap(trapFile.field_location, this, Locations);
|
||||
}
|
||||
}
|
||||
|
||||
private class PropertyFieldFactory : CachedEntityFactory<IFieldSymbol, PropertyField>
|
||||
{
|
||||
public static PropertyFieldFactory Instance { get; } = new PropertyFieldFactory();
|
||||
|
||||
public override PropertyField Create(Context cx, IFieldSymbol init) => new PropertyField(cx, init);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,77 +0,0 @@
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using Microsoft.CodeAnalysis;
|
||||
using Microsoft.CodeAnalysis.CSharp.Syntax;
|
||||
|
||||
namespace Semmle.Extraction.CSharp.Entities
|
||||
{
|
||||
/// <summary>
|
||||
/// Synthetic parameter for extension methods declared using the extension syntax.
|
||||
/// That is, we add a synthetic parameter `s` to `IsValid` in the following example:
|
||||
/// extension(string s) {
|
||||
/// public bool IsValid() { ... }
|
||||
/// }
|
||||
///
|
||||
/// Note, that we use the characteristics of the parameter of the extension type
|
||||
/// to populate the database.
|
||||
/// </summary>
|
||||
internal class SyntheticExtensionParameter : FreshEntity, IParameter
|
||||
{
|
||||
private Method ExtensionMethod { get; }
|
||||
private IParameterSymbol ExtensionParameter { get; }
|
||||
private SyntheticExtensionParameter Original { get; }
|
||||
|
||||
private SyntheticExtensionParameter(Context cx, Method method, IParameterSymbol parameter, SyntheticExtensionParameter? original) : base(cx)
|
||||
{
|
||||
ExtensionMethod = method;
|
||||
ExtensionParameter = parameter;
|
||||
Original = original ?? this;
|
||||
}
|
||||
|
||||
private static int Ordinal => 0;
|
||||
|
||||
private string Name => ExtensionParameter.Name;
|
||||
|
||||
private bool IsSourceDeclaration => ExtensionMethod.Symbol.IsSourceDeclaration();
|
||||
|
||||
protected override void Populate(TextWriter trapFile)
|
||||
{
|
||||
PopulateNullability(trapFile, ExtensionParameter.GetAnnotatedType());
|
||||
PopulateRefKind(trapFile, ExtensionParameter.RefKind);
|
||||
|
||||
var type = Type.Create(Context, ExtensionParameter.Type);
|
||||
var kind = ExtensionParameter.GetParameterKind();
|
||||
trapFile.@params(this, Name, type.TypeRef, Ordinal, kind, ExtensionMethod, Original);
|
||||
|
||||
if (Context.OnlyScaffold)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (Context.ExtractLocation(ExtensionParameter))
|
||||
{
|
||||
var locations = Context.GetLocations(ExtensionParameter);
|
||||
WriteLocationsToTrap(trapFile.param_location, this, locations);
|
||||
}
|
||||
|
||||
if (IsSourceDeclaration)
|
||||
{
|
||||
foreach (var syntax in ExtensionParameter.DeclaringSyntaxReferences
|
||||
.Select(d => d.GetSyntax())
|
||||
.OfType<ParameterSyntax>()
|
||||
.Where(s => s.Type is not null))
|
||||
{
|
||||
TypeMention.Create(Context, syntax.Type!, this, type);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static SyntheticExtensionParameter Create(Context cx, Method method, IParameterSymbol parameter, SyntheticExtensionParameter? original)
|
||||
{
|
||||
var p = new SyntheticExtensionParameter(cx, method, parameter, original);
|
||||
p.TryPopulate();
|
||||
return p;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -20,8 +20,6 @@ namespace Semmle.Extraction.CSharp.Entities
|
||||
public static NamedType Create(Context cx, INamedTypeSymbol type) =>
|
||||
NamedTypeFactory.Instance.CreateEntityFromSymbol(cx, type);
|
||||
|
||||
public NamedType OriginalDefinition => Create(Context, Symbol.OriginalDefinition);
|
||||
|
||||
/// <summary>
|
||||
/// Creates a named type entity from a tuple type. Unlike <see cref="Create"/>, this
|
||||
/// will create an entity for the underlying `System.ValueTuple` struct.
|
||||
@@ -92,25 +90,6 @@ namespace Semmle.Extraction.CSharp.Entities
|
||||
{
|
||||
trapFile.anonymous_types(this);
|
||||
}
|
||||
|
||||
if (Symbol.IsExtension && Symbol.ExtensionParameter is IParameterSymbol parameter)
|
||||
{
|
||||
// For some reason an extension type has a receiver parameter with an empty name
|
||||
// even when there is no parameter.
|
||||
if (!string.IsNullOrEmpty(parameter.Name))
|
||||
{
|
||||
var originalType = OriginalDefinition;
|
||||
// In case this is a constructed generic, we also need to create the unbound parameter.
|
||||
var originalParameter = SymbolEqualityComparer.Default.Equals(Symbol, originalType.Symbol.ExtensionParameter) || originalType.Symbol.ExtensionParameter is null
|
||||
? null
|
||||
: Parameter.Create(Context, originalType.Symbol.ExtensionParameter, originalType);
|
||||
Parameter.Create(Context, parameter, this, originalParameter);
|
||||
}
|
||||
|
||||
// Use the parameter type as the receiver type.
|
||||
var receiverType = Type.Create(Context, parameter.Type).TypeRef;
|
||||
trapFile.extension_receiver_type(this, receiverType);
|
||||
}
|
||||
}
|
||||
|
||||
private readonly Lazy<Type[]> typeArgumentsLazy;
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user