mirror of
https://github.com/github/codeql.git
synced 2026-05-16 12:17:07 +02:00
Compare commits
539 Commits
codeql-cli
...
codeql-cli
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
fb67f93a86 | ||
|
|
ef04f927fb | ||
|
|
7742a5667f | ||
|
|
cf73d96c9d | ||
|
|
597be6a1c0 | ||
|
|
94f1d94a2b | ||
|
|
9fc95f5171 | ||
|
|
924bb92d91 | ||
|
|
60e58f8219 | ||
|
|
6c0c1d558e | ||
|
|
146fc7a8c0 | ||
|
|
7d2b40c657 | ||
|
|
5ccd61ac97 | ||
|
|
bfbb2eef6c | ||
|
|
84be8517bb | ||
|
|
149f3ed5b6 | ||
|
|
47a9f87d9b | ||
|
|
6f609a5ed6 | ||
|
|
16ddb5658f | ||
|
|
d6b71a346e | ||
|
|
8f8f4c2d52 | ||
|
|
90befa0c00 | ||
|
|
ca4c988e97 | ||
|
|
2e0f244376 | ||
|
|
c7099584b4 | ||
|
|
3c161f9c93 | ||
|
|
1fefa989d7 | ||
|
|
953ff9f0d0 | ||
|
|
106254b220 | ||
|
|
5bdf550317 | ||
|
|
c539c2f4fd | ||
|
|
bfe26c1989 | ||
|
|
d0999e3abd | ||
|
|
bf02e478fd | ||
|
|
7d17454a3b | ||
|
|
3e5c2ddeaf | ||
|
|
5f970d9f2f | ||
|
|
218585b52a | ||
|
|
a945f15987 | ||
|
|
5c53677051 | ||
|
|
2dc91a56eb | ||
|
|
6dd6bddff3 | ||
|
|
a4dd4f91d4 | ||
|
|
90a16cfaee | ||
|
|
a27d20dbcd | ||
|
|
76ed386246 | ||
|
|
fea07ebfcb | ||
|
|
9596b7b921 | ||
|
|
b14ece72be | ||
|
|
6a8204d28c | ||
|
|
1ee5728311 | ||
|
|
a22fd39230 | ||
|
|
fa3fba4a00 | ||
|
|
44eeee5757 | ||
|
|
e6dbd525c3 | ||
|
|
522e4d64de | ||
|
|
bed1ec8981 | ||
|
|
6c67475352 | ||
|
|
287a8717a8 | ||
|
|
9ed22610a3 | ||
|
|
36c3084435 | ||
|
|
37af38eed5 | ||
|
|
89e9a253eb | ||
|
|
2fa71f0c17 | ||
|
|
2b10c8aef3 | ||
|
|
0ac1bc4c57 | ||
|
|
cfa62ae434 | ||
|
|
766dc94444 | ||
|
|
542d4631d7 | ||
|
|
f01d5840b0 | ||
|
|
936c4cc79f | ||
|
|
e1bddd9365 | ||
|
|
22e9c212d6 | ||
|
|
26ef33212d | ||
|
|
700543b30b | ||
|
|
22e9b42808 | ||
|
|
50ed0af9da | ||
|
|
e00e3a87ff | ||
|
|
8955fd0bf4 | ||
|
|
f60d759a65 | ||
|
|
00acff293a | ||
|
|
49f24ca8ec | ||
|
|
564a3bd444 | ||
|
|
ece85854cd | ||
|
|
c15ad31b07 | ||
|
|
5116b0c1e5 | ||
|
|
25b836b1b5 | ||
|
|
f2d3bc03aa | ||
|
|
55e5bc4970 | ||
|
|
518fb44a92 | ||
|
|
5634395a32 | ||
|
|
eee4014e94 | ||
|
|
a033057d90 | ||
|
|
624ee1898a | ||
|
|
0cd5366034 | ||
|
|
78c262ca63 | ||
|
|
c3ac20267a | ||
|
|
e172cb3f7a | ||
|
|
677949e409 | ||
|
|
fe10fb37e9 | ||
|
|
ba3fc0a769 | ||
|
|
6611978368 | ||
|
|
16539b4667 | ||
|
|
6235edaa21 | ||
|
|
9a5128f915 | ||
|
|
c5f6820b5d | ||
|
|
5ad42f8bcc | ||
|
|
bee1718469 | ||
|
|
3e914f7ff1 | ||
|
|
42d2de848d | ||
|
|
b5e3168032 | ||
|
|
109d802607 | ||
|
|
71e8730c63 | ||
|
|
eff9f99f44 | ||
|
|
d9fea156f6 | ||
|
|
bcdbd6e283 | ||
|
|
fe94b3b68b | ||
|
|
90401b3ad3 | ||
|
|
d0bd8459a1 | ||
|
|
1c43ceae95 | ||
|
|
5bf2d9442e | ||
|
|
c40d784a4d | ||
|
|
bf6568b928 | ||
|
|
79ad064a93 | ||
|
|
552976d057 | ||
|
|
353cd31ce6 | ||
|
|
48db24d184 | ||
|
|
8459eec239 | ||
|
|
c5179e40c6 | ||
|
|
38830ddc5c | ||
|
|
d5827b5cca | ||
|
|
6c355a1bf8 | ||
|
|
e550d4937c | ||
|
|
62a6b5985d | ||
|
|
2c05624088 | ||
|
|
ac1987f264 | ||
|
|
d57a42a7f7 | ||
|
|
32aaac27ec | ||
|
|
2dc7576232 | ||
|
|
5adc9f8ff0 | ||
|
|
02e4a8b6f7 | ||
|
|
bd3e4d3d7e | ||
|
|
4b6a53b577 | ||
|
|
6cbe000d51 | ||
|
|
c040daab9c | ||
|
|
849823eff6 | ||
|
|
e831c80a23 | ||
|
|
5e02a86542 | ||
|
|
b9f36f37b6 | ||
|
|
9a4a6cfcb8 | ||
|
|
edfdc9812f | ||
|
|
ab505e3281 | ||
|
|
8c27437628 | ||
|
|
12ee93042b | ||
|
|
bac356c9a1 | ||
|
|
68c1a3d389 | ||
|
|
2764d697d2 | ||
|
|
c62d95ac9d | ||
|
|
05bef12ddd | ||
|
|
1df3adf021 | ||
|
|
025f73301b | ||
|
|
e26c199426 | ||
|
|
1203da1b66 | ||
|
|
f79bd3f4cf | ||
|
|
476df7de73 | ||
|
|
29e01748b7 | ||
|
|
11003e685d | ||
|
|
e4daeec2ca | ||
|
|
81977f11a1 | ||
|
|
32fe12a6dd | ||
|
|
83adf793e4 | ||
|
|
0a88425170 | ||
|
|
cd73dcfb04 | ||
|
|
52dc58172d | ||
|
|
544931f73f | ||
|
|
2d02908e7f | ||
|
|
4fcf3fbff8 | ||
|
|
6f40ac15b4 | ||
|
|
55ea55a44f | ||
|
|
36fa0a22f9 | ||
|
|
60bb9a9b06 | ||
|
|
c68cd58f70 | ||
|
|
dca10f8740 | ||
|
|
3f08ff88a4 | ||
|
|
5e6e64b2b7 | ||
|
|
4973523404 | ||
|
|
62fb38d834 | ||
|
|
571f21ba49 | ||
|
|
2d61fc5309 | ||
|
|
8e39ed079e | ||
|
|
389cd5d648 | ||
|
|
092d25451f | ||
|
|
32b86eca50 | ||
|
|
40a58135c2 | ||
|
|
7ef96e3f3c | ||
|
|
5531ef9bc1 | ||
|
|
cbc2dbc14d | ||
|
|
208cf716dc | ||
|
|
d72d8b63ed | ||
|
|
1791c1f1f9 | ||
|
|
d5c4a19efa | ||
|
|
6fbf727309 | ||
|
|
e00390d23a | ||
|
|
d079671ec8 | ||
|
|
cbbc057dd3 | ||
|
|
9fc2a54712 | ||
|
|
d0e30d19c4 | ||
|
|
8de37fec17 | ||
|
|
e712e62f14 | ||
|
|
30b30d65c8 | ||
|
|
6d67e419ff | ||
|
|
29930fa6bf | ||
|
|
a57c6cde30 | ||
|
|
b16f1d3778 | ||
|
|
73d06f26cb | ||
|
|
7ddfa80399 | ||
|
|
fedb9464af | ||
|
|
99b498b891 | ||
|
|
95afe615b5 | ||
|
|
8b03608a4f | ||
|
|
1a6b2b9b82 | ||
|
|
57c2208f7a | ||
|
|
5f1fd57f84 | ||
|
|
6b78313701 | ||
|
|
38fcc61817 | ||
|
|
0db542e9f0 | ||
|
|
4a04f7b66f | ||
|
|
0567864a83 | ||
|
|
18576838d4 | ||
|
|
fe0634574d | ||
|
|
9a00c75460 | ||
|
|
8aa1bff9a5 | ||
|
|
5204255615 | ||
|
|
0222159df5 | ||
|
|
454d13b485 | ||
|
|
16670511de | ||
|
|
ad2aa6d4f8 | ||
|
|
3e0719609f | ||
|
|
1aba0b20cd | ||
|
|
1b5ed129ac | ||
|
|
958c798c3f | ||
|
|
fb6175d10b | ||
|
|
3f718123a6 | ||
|
|
6113d4be9e | ||
|
|
7fccc23dbe | ||
|
|
ac5a74448f | ||
|
|
30ce4069c7 | ||
|
|
4543c66d26 | ||
|
|
5f079c1d51 | ||
|
|
5ba3b679dd | ||
|
|
8c0baefd3b | ||
|
|
78495035a6 | ||
|
|
a3885cd8b2 | ||
|
|
b4cb2c3f13 | ||
|
|
ef6332c581 | ||
|
|
ad6f800022 | ||
|
|
e5f52f086c | ||
|
|
18a2aca42f | ||
|
|
e7a0fc7140 | ||
|
|
f14ccd8c81 | ||
|
|
e54d7c7c73 | ||
|
|
813d4639ca | ||
|
|
76fe3fa502 | ||
|
|
8b936c5dbe | ||
|
|
34800d1519 | ||
|
|
1644376cc9 | ||
|
|
1b1c9c680c | ||
|
|
61a53fadc0 | ||
|
|
2f29c905c3 | ||
|
|
e1cf0a15ed | ||
|
|
52c510bfea | ||
|
|
b2f878229d | ||
|
|
3dd6b3fb69 | ||
|
|
c316d51d41 | ||
|
|
25647badbd | ||
|
|
6445fd805d | ||
|
|
a35e7b27af | ||
|
|
ab495fa843 | ||
|
|
2320d502db | ||
|
|
31867a56fb | ||
|
|
86d9c349ec | ||
|
|
59fa01e386 | ||
|
|
a6f8af0de5 | ||
|
|
f6f5b7e1e9 | ||
|
|
275724000b | ||
|
|
939f3e83aa | ||
|
|
d69fe20d7d | ||
|
|
9f5de6b4f2 | ||
|
|
6d60595d73 | ||
|
|
e1f3d5b374 | ||
|
|
5cdfb77504 | ||
|
|
8ee35231c2 | ||
|
|
55525279ca | ||
|
|
4d7c84178a | ||
|
|
eb37255c4b | ||
|
|
164cae845d | ||
|
|
b8d01ed21b | ||
|
|
cc25d30fed | ||
|
|
07e5479aff | ||
|
|
bc419fd35c | ||
|
|
772503bad8 | ||
|
|
beff080ee7 | ||
|
|
f4edff9452 | ||
|
|
4503c625b4 | ||
|
|
28fec0c129 | ||
|
|
445cca1432 | ||
|
|
497135593c | ||
|
|
2214a944bb | ||
|
|
a0c35516bd | ||
|
|
42cbe0734e | ||
|
|
516b84b59a | ||
|
|
4f1ad0ff5d | ||
|
|
ccc4d8ae3f | ||
|
|
2cb0e81da0 | ||
|
|
aae5333325 | ||
|
|
fa59a8ae24 | ||
|
|
4526afc29f | ||
|
|
1c5a9053f9 | ||
|
|
5a08adc06c | ||
|
|
0b8b75ac25 | ||
|
|
b7125a009e | ||
|
|
97a0b9f0ca | ||
|
|
46a5035543 | ||
|
|
bb71790a53 | ||
|
|
db3f22a2e8 | ||
|
|
3d445be926 | ||
|
|
ede05b54ea | ||
|
|
9a94d0474c | ||
|
|
9e9d57bac5 | ||
|
|
8e3c373548 | ||
|
|
5bfeede364 | ||
|
|
f49531b3ca | ||
|
|
0f4f0b880a | ||
|
|
e0a7889b71 | ||
|
|
bd09aad7d5 | ||
|
|
980c4cf5f4 | ||
|
|
544015d0a6 | ||
|
|
b974a84bef | ||
|
|
aed0e688f5 | ||
|
|
13a5249a9d | ||
|
|
91752e5307 | ||
|
|
330505c524 | ||
|
|
73850f1b56 | ||
|
|
2bd4ccee45 | ||
|
|
df09f02981 | ||
|
|
732c60c07c | ||
|
|
0f6bae0ae1 | ||
|
|
93dad867cd | ||
|
|
3b1e062985 | ||
|
|
0adece7cde | ||
|
|
739748c29b | ||
|
|
47d9e8a357 | ||
|
|
7024b07dd2 | ||
|
|
c975ae5231 | ||
|
|
c4e0dda178 | ||
|
|
b11b091559 | ||
|
|
4ce04e4749 | ||
|
|
01cc19cffc | ||
|
|
793d2c79de | ||
|
|
f76211c64a | ||
|
|
ffa700c825 | ||
|
|
bd8a127565 | ||
|
|
c488086135 | ||
|
|
452d307fd5 | ||
|
|
7100ca4262 | ||
|
|
a7fecaaa1b | ||
|
|
45e0a929a8 | ||
|
|
8e7d62600d | ||
|
|
f1f4ddb76c | ||
|
|
fafc2ddc0b | ||
|
|
f837d90060 | ||
|
|
fdc5ae375b | ||
|
|
e250c711aa | ||
|
|
cabcb83b2f | ||
|
|
e36080061d | ||
|
|
6c2a3a68b6 | ||
|
|
a556152b9d | ||
|
|
e58a8330cd | ||
|
|
949fc3745a | ||
|
|
a326ce34a8 | ||
|
|
9018401722 | ||
|
|
6c2e0f7658 | ||
|
|
dc26a57548 | ||
|
|
82e2afc93c | ||
|
|
7ed1c0a2ee | ||
|
|
ecd247bf16 | ||
|
|
ad590f30c1 | ||
|
|
075041f1ae | ||
|
|
7e674f3227 | ||
|
|
573ab025b4 | ||
|
|
7bdf2ab9d2 | ||
|
|
8f6f7d0985 | ||
|
|
3d7049265f | ||
|
|
ccd07b8a63 | ||
|
|
55abc52c61 | ||
|
|
e40f896b17 | ||
|
|
d05901ad3f | ||
|
|
7f00a7f67e | ||
|
|
b08c972cc3 | ||
|
|
15980cb1da | ||
|
|
75bd4a7a12 | ||
|
|
da2f77d615 | ||
|
|
3dbfb9fa4b | ||
|
|
699ed50432 | ||
|
|
f484d95081 | ||
|
|
ffaf1c0a24 | ||
|
|
201512525b | ||
|
|
b8581e89bf | ||
|
|
7d34f6e262 | ||
|
|
67b52e29e0 | ||
|
|
3d6765ba1c | ||
|
|
fa9677d615 | ||
|
|
9d645508ea | ||
|
|
114db99dca | ||
|
|
8ce2618b7d | ||
|
|
e8ef58d381 | ||
|
|
f8d0a0d509 | ||
|
|
80d543ecae | ||
|
|
65ca8849f2 | ||
|
|
73eb3e262d | ||
|
|
60ee92d834 | ||
|
|
d89967ce8e | ||
|
|
dd415386ea | ||
|
|
64a7d7d836 | ||
|
|
5e536fb121 | ||
|
|
7bd62087a4 | ||
|
|
656ebab776 | ||
|
|
e1089c8d89 | ||
|
|
11566ee256 | ||
|
|
e4ec79255b | ||
|
|
c30dffc7b9 | ||
|
|
1d461ff5ad | ||
|
|
6ae1ea73f7 | ||
|
|
0b9691aca2 | ||
|
|
9a9e9ac23c | ||
|
|
5414bd2716 | ||
|
|
048afc2c88 | ||
|
|
f76d85c9c6 | ||
|
|
fa926456ef | ||
|
|
1c38fb6ad6 | ||
|
|
b3b30a15b8 | ||
|
|
4ca508d420 | ||
|
|
fbcb65a5d9 | ||
|
|
701569bb20 | ||
|
|
b35271a2ca | ||
|
|
28047fe625 | ||
|
|
e7044061fb | ||
|
|
f8f5094452 | ||
|
|
51b1ea84d3 | ||
|
|
49ced5fd9d | ||
|
|
d6d2855626 | ||
|
|
c37ab8f98e | ||
|
|
1fd60c7671 | ||
|
|
82e9ea2da0 | ||
|
|
a299174f4d | ||
|
|
fdefb4d23a | ||
|
|
d2da49220b | ||
|
|
4b9c9e7a5a | ||
|
|
df8029ff87 | ||
|
|
4140121e96 | ||
|
|
7d6a1f72d5 | ||
|
|
c6500e2759 | ||
|
|
470bc7d6da | ||
|
|
d1175276ca | ||
|
|
d125e224ac | ||
|
|
dc3b7aaab0 | ||
|
|
8d5eb407ad | ||
|
|
224e5dece4 | ||
|
|
dd73399238 | ||
|
|
8e6f920ae2 | ||
|
|
75cab960e2 | ||
|
|
6fe76b3b11 | ||
|
|
ff6e598f72 | ||
|
|
fc5d5b4fcc | ||
|
|
50fdc99b8c | ||
|
|
48475e66af | ||
|
|
93b3f65388 | ||
|
|
a0311c0ea3 | ||
|
|
930b17a2e2 | ||
|
|
efe413cbd0 | ||
|
|
7ff1c12e8f | ||
|
|
7ae2b7698e | ||
|
|
d183dcd6fc | ||
|
|
c11b464492 | ||
|
|
b3631545d4 | ||
|
|
c47a9ddf83 | ||
|
|
4e478c3629 | ||
|
|
7aca94b1ca | ||
|
|
c70633a0f7 | ||
|
|
58a3260c96 | ||
|
|
a11b271d6e | ||
|
|
48254800b1 | ||
|
|
07ac8a5d81 | ||
|
|
2b31928c7b | ||
|
|
948623e767 | ||
|
|
fd309d6e49 | ||
|
|
33fc2bab33 | ||
|
|
beb7750c21 | ||
|
|
86198e3c43 | ||
|
|
bd1c6e6352 | ||
|
|
3d988e8e94 | ||
|
|
812fdbe412 | ||
|
|
ab432ec2e9 | ||
|
|
5942edf2d9 | ||
|
|
f0135e93c5 | ||
|
|
4ba89230db | ||
|
|
0bf0cbae8f | ||
|
|
b061c4d083 | ||
|
|
98949937dd | ||
|
|
78b88d3a44 | ||
|
|
9ab29f9be0 | ||
|
|
dabc5d54c9 | ||
|
|
03d6528687 | ||
|
|
1b117900c2 | ||
|
|
d6ca1ca846 | ||
|
|
196f6e1931 | ||
|
|
657e26a375 | ||
|
|
4f4baee888 | ||
|
|
aa058c2cca | ||
|
|
a18f3b6859 | ||
|
|
67ab0fee83 | ||
|
|
6e3fd25b09 | ||
|
|
157487d8f2 | ||
|
|
1ac3706e75 | ||
|
|
6fc963177c | ||
|
|
ac55cf9544 | ||
|
|
6fbae45d49 | ||
|
|
6a1e26c566 | ||
|
|
384e17a4ef | ||
|
|
26b8a394b3 | ||
|
|
a660eaba95 | ||
|
|
acddb2c272 | ||
|
|
d790c6df57 | ||
|
|
fab96d9539 | ||
|
|
5ca9ff2082 | ||
|
|
341f553866 | ||
|
|
704e2966cb | ||
|
|
d27d4fdb27 | ||
|
|
47fac883b8 |
1
.github/workflows/ql-for-ql-build.yml
vendored
1
.github/workflows/ql-for-ql-build.yml
vendored
@@ -27,6 +27,7 @@ jobs:
|
||||
uses: github/codeql-action/init@main
|
||||
with:
|
||||
languages: javascript # does not matter
|
||||
tools: nightly
|
||||
- uses: ./.github/actions/os-version
|
||||
id: os_version
|
||||
### Build the extractor ###
|
||||
|
||||
2
.github/workflows/ql-for-ql-tests.yml
vendored
2
.github/workflows/ql-for-ql-tests.yml
vendored
@@ -30,6 +30,7 @@ jobs:
|
||||
uses: github/codeql-action/init@main
|
||||
with:
|
||||
languages: javascript # does not matter
|
||||
tools: nightly
|
||||
- uses: ./.github/actions/os-version
|
||||
id: os_version
|
||||
- uses: actions/cache@v3
|
||||
@@ -75,6 +76,7 @@ jobs:
|
||||
uses: github/codeql-action/init@main
|
||||
with:
|
||||
languages: javascript # does not matter
|
||||
tools: nightly
|
||||
- uses: ./.github/actions/os-version
|
||||
id: os_version
|
||||
- uses: actions/cache@v3
|
||||
|
||||
21
MODULE.bazel
21
MODULE.bazel
@@ -24,7 +24,7 @@ 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.1.3-codeql.1")
|
||||
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")
|
||||
@@ -221,10 +221,6 @@ use_repo(
|
||||
kotlin_extractor_deps,
|
||||
"codeql_kotlin_defaults",
|
||||
"codeql_kotlin_embeddable",
|
||||
"kotlin-compiler-1.6.0",
|
||||
"kotlin-compiler-1.6.20",
|
||||
"kotlin-compiler-1.7.0",
|
||||
"kotlin-compiler-1.7.20",
|
||||
"kotlin-compiler-1.8.0",
|
||||
"kotlin-compiler-1.9.0-Beta",
|
||||
"kotlin-compiler-1.9.20-Beta",
|
||||
@@ -234,10 +230,7 @@ use_repo(
|
||||
"kotlin-compiler-2.1.20-Beta1",
|
||||
"kotlin-compiler-2.2.0-Beta1",
|
||||
"kotlin-compiler-2.2.20-Beta2",
|
||||
"kotlin-compiler-embeddable-1.6.0",
|
||||
"kotlin-compiler-embeddable-1.6.20",
|
||||
"kotlin-compiler-embeddable-1.7.0",
|
||||
"kotlin-compiler-embeddable-1.7.20",
|
||||
"kotlin-compiler-2.3.0",
|
||||
"kotlin-compiler-embeddable-1.8.0",
|
||||
"kotlin-compiler-embeddable-1.9.0-Beta",
|
||||
"kotlin-compiler-embeddable-1.9.20-Beta",
|
||||
@@ -247,10 +240,7 @@ use_repo(
|
||||
"kotlin-compiler-embeddable-2.1.20-Beta1",
|
||||
"kotlin-compiler-embeddable-2.2.0-Beta1",
|
||||
"kotlin-compiler-embeddable-2.2.20-Beta2",
|
||||
"kotlin-stdlib-1.6.0",
|
||||
"kotlin-stdlib-1.6.20",
|
||||
"kotlin-stdlib-1.7.0",
|
||||
"kotlin-stdlib-1.7.20",
|
||||
"kotlin-compiler-embeddable-2.3.0",
|
||||
"kotlin-stdlib-1.8.0",
|
||||
"kotlin-stdlib-1.9.0-Beta",
|
||||
"kotlin-stdlib-1.9.20-Beta",
|
||||
@@ -260,14 +250,15 @@ use_repo(
|
||||
"kotlin-stdlib-2.1.20-Beta1",
|
||||
"kotlin-stdlib-2.2.0-Beta1",
|
||||
"kotlin-stdlib-2.2.20-Beta2",
|
||||
"kotlin-stdlib-2.3.0",
|
||||
)
|
||||
|
||||
go_sdk = use_extension("@rules_go//go:extensions.bzl", "go_sdk")
|
||||
go_sdk.download(version = "1.25.0")
|
||||
go_sdk.download(version = "1.26.0")
|
||||
|
||||
go_deps = use_extension("@gazelle//:extensions.bzl", "go_deps")
|
||||
go_deps.from_file(go_mod = "//go/extractor:go.mod")
|
||||
use_repo(go_deps, "org_golang_x_mod", "org_golang_x_tools")
|
||||
use_repo(go_deps, "com_github_stretchr_testify", "org_golang_x_mod", "org_golang_x_tools")
|
||||
|
||||
ripunzip_archive = use_repo_rule("//misc/ripunzip:ripunzip.bzl", "ripunzip_archive")
|
||||
|
||||
|
||||
@@ -1,3 +1,13 @@
|
||||
## 0.4.28
|
||||
|
||||
No user-facing changes.
|
||||
|
||||
## 0.4.27
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* Fixed a crash when analysing a `${{ ... }}` expression over around 300 characters in length.
|
||||
|
||||
## 0.4.26
|
||||
|
||||
### Major Analysis Improvements
|
||||
|
||||
5
actions/ql/lib/change-notes/released/0.4.27.md
Normal file
5
actions/ql/lib/change-notes/released/0.4.27.md
Normal file
@@ -0,0 +1,5 @@
|
||||
## 0.4.27
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* Fixed a crash when analysing a `${{ ... }}` expression over around 300 characters in length.
|
||||
3
actions/ql/lib/change-notes/released/0.4.28.md
Normal file
3
actions/ql/lib/change-notes/released/0.4.28.md
Normal file
@@ -0,0 +1,3 @@
|
||||
## 0.4.28
|
||||
|
||||
No user-facing changes.
|
||||
@@ -1,2 +1,2 @@
|
||||
---
|
||||
lastReleaseVersion: 0.4.26
|
||||
lastReleaseVersion: 0.4.28
|
||||
|
||||
@@ -27,8 +27,8 @@ string getADelimitedExpression(YamlString s, int offset) {
|
||||
// not just the last (greedy match) or first (reluctant match).
|
||||
result =
|
||||
s.getValue()
|
||||
.regexpFind("\\$\\{\\{(?:[^}]|}(?!}))*\\}\\}", _, offset)
|
||||
.regexpCapture("(\\$\\{\\{(?:[^}]|}(?!}))*\\}\\})", 1)
|
||||
.regexpFind("\\$\\{\\{(?:[^}]|}(?!}))*+\\}\\}", _, offset)
|
||||
.regexpCapture("(\\$\\{\\{(?:[^}]|}(?!}))*+\\}\\})", 1)
|
||||
.trim()
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
name: codeql/actions-all
|
||||
version: 0.4.26
|
||||
version: 0.4.28
|
||||
library: true
|
||||
warnOnImplicitThis: true
|
||||
dependencies:
|
||||
|
||||
@@ -1,3 +1,11 @@
|
||||
## 0.6.20
|
||||
|
||||
No user-facing changes.
|
||||
|
||||
## 0.6.19
|
||||
|
||||
No user-facing changes.
|
||||
|
||||
## 0.6.18
|
||||
|
||||
No user-facing changes.
|
||||
|
||||
3
actions/ql/src/change-notes/released/0.6.19.md
Normal file
3
actions/ql/src/change-notes/released/0.6.19.md
Normal file
@@ -0,0 +1,3 @@
|
||||
## 0.6.19
|
||||
|
||||
No user-facing changes.
|
||||
3
actions/ql/src/change-notes/released/0.6.20.md
Normal file
3
actions/ql/src/change-notes/released/0.6.20.md
Normal file
@@ -0,0 +1,3 @@
|
||||
## 0.6.20
|
||||
|
||||
No user-facing changes.
|
||||
@@ -1,2 +1,2 @@
|
||||
---
|
||||
lastReleaseVersion: 0.6.18
|
||||
lastReleaseVersion: 0.6.20
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
name: codeql/actions-queries
|
||||
version: 0.6.18
|
||||
version: 0.6.20
|
||||
library: false
|
||||
warnOnImplicitThis: true
|
||||
groups: [actions, queries]
|
||||
|
||||
1002
actions/ql/test/library-tests/very-long-expression/.github/workflows/very_long_expression_node.yml
vendored
Normal file
1002
actions/ql/test/library-tests/very-long-expression/.github/workflows/very_long_expression_node.yml
vendored
Normal file
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1 @@
|
||||
| 97418 |
|
||||
@@ -0,0 +1,5 @@
|
||||
import codeql.actions.ast.internal.Ast
|
||||
|
||||
int getAnExpressionLength() { result = any(ExpressionImpl e).toString().length() }
|
||||
|
||||
select max(getAnExpressionLength())
|
||||
2517
cpp/downgrades/7e7c2f55670f8123d514cf542ccb1938118ac561/old.dbscheme
Normal file
2517
cpp/downgrades/7e7c2f55670f8123d514cf542ccb1938118ac561/old.dbscheme
Normal file
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,5 @@
|
||||
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
|
||||
2483
cpp/downgrades/83100310bf73eefc37c1d8d0ac98b2ca3019c7b6/old.dbscheme
Normal file
2483
cpp/downgrades/83100310bf73eefc37c1d8d0ac98b2ca3019c7b6/old.dbscheme
Normal file
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,2 @@
|
||||
description: Sections for databaseMetadata and overlayChangedFiles
|
||||
compatibility: full
|
||||
2489
cpp/downgrades/9439176c1d1312787926458dd54d65a849069118/old.dbscheme
Normal file
2489
cpp/downgrades/9439176c1d1312787926458dd54d65a849069118/old.dbscheme
Normal file
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,13 @@
|
||||
class PreprocessorDirective extends @preprocdirect {
|
||||
string toString() { none() }
|
||||
}
|
||||
|
||||
class Location extends @location_default {
|
||||
string toString() { none() }
|
||||
}
|
||||
|
||||
from PreprocessorDirective ppd, int kind, int kind_new, Location l
|
||||
where
|
||||
preprocdirects(ppd, kind, l) and
|
||||
if kind = 17 then kind_new = /* ppd_warning */ 18 else kind_new = kind
|
||||
select ppd, kind_new, l
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,4 @@
|
||||
description: Support embed preprocessor directive
|
||||
compatibility: partial
|
||||
embeds.rel: delete
|
||||
preprocdirects.rel: run preprocdirects.qlo
|
||||
@@ -1,3 +1,27 @@
|
||||
## 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
|
||||
|
||||
* Added a subclass `Embed` of `PreprocessorDirective` for C23 and C++26 `#embed` preprocessor directives.
|
||||
* Added modules `DataFlow::ParameterizedBarrierGuard` and `DataFlow::ParameterizedInstructionBarrierGuard`. These modules provide the same features as `DataFlow::BarrierGuard` and `DataFlow::InstructionBarrierGuard`, but allow for an additional parameter to support properly using them in dataflow configurations that uses flow states.
|
||||
|
||||
### Minor Analysis Improvements
|
||||
|
||||
* The `Buffer.qll` library will no longer report incorrect buffer sizes on certain malformed databases. As a result, the queries `cpp/static-buffer-overflow`, `cpp/overflow-buffer`, `cpp/badly-bounded-write`, `cpp/overrunning-write`, `cpp/overrunning-write-with-float`, and `cpp/very-likely-overrunning-write` will report fewer false positives on such databases.
|
||||
* Added `taint` summary models and `sql-injection` barrier models for the MySQL `mysql_real_escape_string` and `mysql_real_escape_string_quote` escaping functions.
|
||||
* The predicate `SummarizedCallable.propagatesFlow` has been extended with the columns `Provenance p` and `boolean isExact`, and as a consequence the predicates `SummarizedCallable.hasProvenance` and `SummarizedCallable.hasExactModel` have been removed.
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* Fixed a bug in the `GuardCondition` library which sometimes prevented binary logical operators from being recognized as guard conditions. As a result, queries using `GuardCondition` may see improved results.
|
||||
* Fixed a bug which caused `Node.asDefinition()` to not have a result for certain assignments.
|
||||
|
||||
## 7.0.0
|
||||
|
||||
### Breaking Changes
|
||||
|
||||
17
cpp/ql/lib/change-notes/released/7.1.0.md
Normal file
17
cpp/ql/lib/change-notes/released/7.1.0.md
Normal file
@@ -0,0 +1,17 @@
|
||||
## 7.1.0
|
||||
|
||||
### New Features
|
||||
|
||||
* Added a subclass `Embed` of `PreprocessorDirective` for C23 and C++26 `#embed` preprocessor directives.
|
||||
* Added modules `DataFlow::ParameterizedBarrierGuard` and `DataFlow::ParameterizedInstructionBarrierGuard`. These modules provide the same features as `DataFlow::BarrierGuard` and `DataFlow::InstructionBarrierGuard`, but allow for an additional parameter to support properly using them in dataflow configurations that uses flow states.
|
||||
|
||||
### Minor Analysis Improvements
|
||||
|
||||
* The `Buffer.qll` library will no longer report incorrect buffer sizes on certain malformed databases. As a result, the queries `cpp/static-buffer-overflow`, `cpp/overflow-buffer`, `cpp/badly-bounded-write`, `cpp/overrunning-write`, `cpp/overrunning-write-with-float`, and `cpp/very-likely-overrunning-write` will report fewer false positives on such databases.
|
||||
* Added `taint` summary models and `sql-injection` barrier models for the MySQL `mysql_real_escape_string` and `mysql_real_escape_string_quote` escaping functions.
|
||||
* The predicate `SummarizedCallable.propagatesFlow` has been extended with the columns `Provenance p` and `boolean isExact`, and as a consequence the predicates `SummarizedCallable.hasProvenance` and `SummarizedCallable.hasExactModel` have been removed.
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* Fixed a bug in the `GuardCondition` library which sometimes prevented binary logical operators from being recognized as guard conditions. As a result, queries using `GuardCondition` may see improved results.
|
||||
* Fixed a bug which caused `Node.asDefinition()` to not have a result for certain assignments.
|
||||
5
cpp/ql/lib/change-notes/released/7.1.1.md
Normal file
5
cpp/ql/lib/change-notes/released/7.1.1.md
Normal file
@@ -0,0 +1,5 @@
|
||||
## 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,2 +1,2 @@
|
||||
---
|
||||
lastReleaseVersion: 7.0.0
|
||||
lastReleaseVersion: 7.1.1
|
||||
|
||||
14
cpp/ql/lib/ext/MySql.model.yml
Normal file
14
cpp/ql/lib/ext/MySql.model.yml
Normal file
@@ -0,0 +1,14 @@
|
||||
# partial model of the MySQL api
|
||||
extensions:
|
||||
- addsTo:
|
||||
pack: codeql/cpp-all
|
||||
extensible: summaryModel
|
||||
data: # namespace, type, subtypes, name, signature, ext, input, output, kind, provenance
|
||||
- ["", "", False, "mysql_real_escape_string", "", "", "Argument[*2]", "Argument[*1]", "taint", "manual"]
|
||||
- ["", "", False, "mysql_real_escape_string_quote", "", "", "Argument[*2]", "Argument[*1]", "taint", "manual"]
|
||||
- addsTo:
|
||||
pack: codeql/cpp-all
|
||||
extensible: barrierModel
|
||||
data: # namespace, type, subtypes, name, signature, ext, output, kind, provenance
|
||||
- ["", "", False, "mysql_real_escape_string", "", "", "Argument[*1]", "sql-injection", "manual"]
|
||||
- ["", "", False, "mysql_real_escape_string_quote", "", "", "Argument[*1]", "sql-injection", "manual"]
|
||||
@@ -24,6 +24,13 @@ 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
|
||||
@@ -46,4 +53,6 @@ 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"]
|
||||
- ["", "", False, "RtlInitUnicodeString", "", "", "Argument[*1]", "Argument[*0].Field[*Buffer]", "value", "manual"]
|
||||
# winhttp.h
|
||||
- ["", "", False, "WinHttpCrackUrl", "", "", "Argument[*0]", "Argument[*3]", "taint", "manual"]
|
||||
41
cpp/ql/lib/ext/azure.core.model.yml
Normal file
41
cpp/ql/lib/ext/azure.core.model.yml
Normal file
@@ -0,0 +1,41 @@
|
||||
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: 7.0.0
|
||||
version: 7.1.1
|
||||
groups: cpp
|
||||
dbscheme: semmlecode.cpp.dbscheme
|
||||
extractor: cpp
|
||||
|
||||
@@ -192,6 +192,15 @@ class Element extends ElementBase {
|
||||
*/
|
||||
predicate isAffectedByMacro() { affectedByMacro(this) }
|
||||
|
||||
/**
|
||||
* INTERNAL: Do not use.
|
||||
*
|
||||
* Holds if this element is affected by the expansion of `mi`.
|
||||
*/
|
||||
predicate isAffectedByMacro(MacroInvocation mi) {
|
||||
affectedbymacroexpansion(underlyingElement(this), unresolveElement(mi))
|
||||
}
|
||||
|
||||
private Element getEnclosingElementPref() {
|
||||
enclosingfunction(underlyingElement(this), unresolveElement(result)) or
|
||||
result.(Function) = stmtEnclosingElement(this) or
|
||||
|
||||
@@ -239,6 +239,9 @@ class MacroInvocation extends MacroAccess {
|
||||
macro_argument_unexpanded(underlyingElement(this), i, result)
|
||||
}
|
||||
|
||||
/** Gets the number of arguments for this macro invocation. */
|
||||
int getNumberOfArguments() { result = count(int i | exists(this.getUnexpandedArgument(i)) | i) }
|
||||
|
||||
/**
|
||||
* Gets the `i`th _expanded_ argument of this macro invocation, where the
|
||||
* first argument has `i = 0`. The result has been expanded for macros _and_
|
||||
|
||||
@@ -328,3 +328,27 @@ class PreprocessorPragma extends PreprocessorDirective, @ppd_pragma {
|
||||
class PreprocessorLine extends PreprocessorDirective, @ppd_line {
|
||||
override string toString() { result = "#line " + this.getHead() }
|
||||
}
|
||||
|
||||
/**
|
||||
* A C23 or C++26 `#embed` preprocessor directive. For example, the following code
|
||||
* contains one `Embed` directive:
|
||||
* ```cpp
|
||||
* char arr[] = {
|
||||
* #embed "bin"
|
||||
* };
|
||||
* ```
|
||||
*/
|
||||
class Embed extends PreprocessorDirective, @ppd_embed {
|
||||
override string toString() { result = "#embed " + this.getIncludeText() }
|
||||
|
||||
/**
|
||||
* Gets the token which occurs after `#embed`, for example `"filename"`
|
||||
* or `<filename>`.
|
||||
*/
|
||||
string getIncludeText() { result = this.getHead() }
|
||||
|
||||
/**
|
||||
* Gets the file directly embedded by this `#embed`.
|
||||
*/
|
||||
File getEmbeddedFile() { embeds(underlyingElement(this), unresolveElement(result)) }
|
||||
}
|
||||
|
||||
@@ -62,11 +62,13 @@ private Class getRootType(FieldAccess fa) {
|
||||
* unspecified type of `v` is a `ReferenceType`.
|
||||
*/
|
||||
private int getVariableSize(Variable v) {
|
||||
exists(Type t |
|
||||
t = v.getUnspecifiedType() and
|
||||
not t instanceof ReferenceType and
|
||||
result = t.getSize()
|
||||
)
|
||||
result =
|
||||
unique(Type t |
|
||||
t = v.getUnspecifiedType() and
|
||||
not t instanceof ReferenceType
|
||||
|
|
||||
t.getSize()
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -79,30 +81,32 @@ private int getSize(VariableAccess va) {
|
||||
not v instanceof Field and
|
||||
result = getVariableSize(v)
|
||||
or
|
||||
exists(Class c, int trueSize |
|
||||
// Otherwise, we find the "outermost" object and compute the size
|
||||
// as the difference between the size of the type of the "outermost
|
||||
// object" and the offset of the field relative to that type.
|
||||
// For example, consider the following structs:
|
||||
// ```
|
||||
// struct S {
|
||||
// uint32_t x;
|
||||
// uint32_t y;
|
||||
// };
|
||||
// struct S2 {
|
||||
// S s;
|
||||
// uint32_t z;
|
||||
// };
|
||||
// ```
|
||||
// Given an object `S2 s2` the size of the buffer `&s2.s.y`
|
||||
// is the size of the base object type (i.e., `S2`) minutes the offset
|
||||
// of `y` relative to the type `S2` (i.e., `4`). So the size of the
|
||||
// buffer is `12 - 4 = 8`.
|
||||
c = getRootType(va) and
|
||||
// we calculate the size based on the last field, to avoid including any padding after it
|
||||
trueSize = max(Field f | | f.getOffsetInClass(c) + getVariableSize(f)) and
|
||||
result = trueSize - v.(Field).getOffsetInClass(c)
|
||||
)
|
||||
result =
|
||||
unique(Class c, int trueSize |
|
||||
// Otherwise, we find the "outermost" object and compute the size
|
||||
// as the difference between the size of the type of the "outermost
|
||||
// object" and the offset of the field relative to that type.
|
||||
// For example, consider the following structs:
|
||||
// ```
|
||||
// struct S {
|
||||
// uint32_t x;
|
||||
// uint32_t y;
|
||||
// };
|
||||
// struct S2 {
|
||||
// S s;
|
||||
// uint32_t z;
|
||||
// };
|
||||
// ```
|
||||
// Given an object `S2 s2` the size of the buffer `&s2.s.y`
|
||||
// is the size of the base object type (i.e., `S2`) minus the offset
|
||||
// of `y` relative to the type `S2` (i.e., `4`). So the size of the
|
||||
// buffer is `12 - 4 = 8`.
|
||||
c = getRootType(va) and
|
||||
// we calculate the size based on the last field, to avoid including any padding after it
|
||||
trueSize = max(Field f | | f.getOffsetInClass(c) + getVariableSize(f))
|
||||
|
|
||||
trueSize - v.(Field).getOffsetInClass(c)
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -116,12 +120,8 @@ private int isSource(Expr bufferExpr, Element why) {
|
||||
exists(Variable bufferVar | bufferVar = bufferExpr.(VariableAccess).getTarget() |
|
||||
// buffer is a fixed size array
|
||||
exists(bufferVar.getUnspecifiedType().(ArrayType).getSize()) and
|
||||
result =
|
||||
unique(int size | // more generous than .getSize() itself, when the array is a class field or similar.
|
||||
size = getSize(bufferExpr)
|
||||
|
|
||||
size
|
||||
) and
|
||||
// more generous than .getSize() itself, when the array is a class field or similar.
|
||||
result = getSize(bufferExpr) and
|
||||
why = bufferVar and
|
||||
not memberMayBeVarSize(_, bufferVar) and
|
||||
not exists(BuiltInOperationBuiltInOffsetOf offsetof | offsetof.getAChild*() = bufferExpr) and
|
||||
|
||||
@@ -8,7 +8,8 @@ import semmle.code.cpp.ir.IR
|
||||
private import codeql.util.Void
|
||||
private import codeql.controlflow.Guards as SharedGuards
|
||||
private import semmle.code.cpp.ir.ValueNumbering
|
||||
private import semmle.code.cpp.ir.implementation.raw.internal.TranslatedExpr
|
||||
private import semmle.code.cpp.ir.implementation.raw.internal.TranslatedExpr as TE
|
||||
private import semmle.code.cpp.ir.implementation.raw.internal.TranslatedFunction as TF
|
||||
private import semmle.code.cpp.ir.implementation.raw.internal.InstructionTag
|
||||
|
||||
private class BasicBlock = IRCfg::BasicBlock;
|
||||
@@ -683,24 +684,26 @@ final class GuardCondition = GuardConditionImpl;
|
||||
*/
|
||||
private class GuardConditionFromBinaryLogicalOperator extends GuardConditionImpl instanceof Cpp::BinaryLogicalOperation
|
||||
{
|
||||
GuardConditionImpl l;
|
||||
GuardConditionImpl r;
|
||||
|
||||
GuardConditionFromBinaryLogicalOperator() {
|
||||
super.getLeftOperand() = l and
|
||||
super.getRightOperand() = r
|
||||
}
|
||||
|
||||
override predicate valueControls(Cpp::BasicBlock controlled, GuardValue v) {
|
||||
exists(Cpp::BinaryLogicalOperation binop, GuardCondition lhs, GuardCondition rhs |
|
||||
this = binop and
|
||||
lhs = binop.getLeftOperand() and
|
||||
rhs = binop.getRightOperand() and
|
||||
lhs.valueControls(controlled, v) and
|
||||
rhs.valueControls(controlled, v)
|
||||
)
|
||||
// `l || r` does not control `r` even though `l` does.
|
||||
not r.(Cpp::Expr).getBasicBlock() = controlled and
|
||||
l.valueControls(controlled, v)
|
||||
or
|
||||
r.valueControls(controlled, v)
|
||||
}
|
||||
|
||||
override predicate valueControlsEdge(Cpp::BasicBlock pred, Cpp::BasicBlock succ, GuardValue v) {
|
||||
exists(Cpp::BinaryLogicalOperation binop, GuardCondition lhs, GuardCondition rhs |
|
||||
this = binop and
|
||||
lhs = binop.getLeftOperand() and
|
||||
rhs = binop.getRightOperand() and
|
||||
lhs.valueControlsEdge(pred, succ, v) and
|
||||
rhs.valueControlsEdge(pred, succ, v)
|
||||
)
|
||||
l.valueControlsEdge(pred, succ, v)
|
||||
or
|
||||
r.valueControlsEdge(pred, succ, v)
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
@@ -1026,7 +1029,7 @@ private class GuardConditionFromIR extends GuardConditionImpl {
|
||||
|
||||
private predicate excludeAsControlledInstruction(Instruction instr) {
|
||||
// Exclude the temporaries generated by a ternary expression.
|
||||
exists(TranslatedConditionalExpr tce |
|
||||
exists(TE::TranslatedConditionalExpr tce |
|
||||
instr = tce.getInstruction(ConditionValueFalseStoreTag())
|
||||
or
|
||||
instr = tce.getInstruction(ConditionValueTrueStoreTag())
|
||||
@@ -1038,6 +1041,14 @@ private predicate excludeAsControlledInstruction(Instruction instr) {
|
||||
or
|
||||
// Exclude unreached instructions, as their AST is the whole function and not a block.
|
||||
instr instanceof UnreachedInstruction
|
||||
or
|
||||
// Exclude instructions generated by a translated function as they map to the function itself
|
||||
// and the function is considered the last basic block of a function body.
|
||||
any(TF::TranslatedFunction tf).getInstruction(_) = instr
|
||||
or
|
||||
// `ChiInstruction`s generated by instructions in the above case don't come from `getInstruction` (since they are generated by AliasedSSA)
|
||||
// so we need to special case them.
|
||||
excludeAsControlledInstruction(instr.(ChiInstruction).getPartial())
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -95,6 +95,7 @@
|
||||
|
||||
import cpp
|
||||
private import new.DataFlow
|
||||
private import semmle.code.cpp.controlflow.IRGuards
|
||||
private import semmle.code.cpp.ir.dataflow.internal.DataFlowPrivate as Private
|
||||
private import semmle.code.cpp.ir.dataflow.internal.DataFlowUtil
|
||||
private import internal.FlowSummaryImpl
|
||||
@@ -367,6 +368,8 @@ private predicate elementSpec(
|
||||
) {
|
||||
sourceModel(namespace, type, subtypes, name, signature, ext, _, _, _, _) or
|
||||
sinkModel(namespace, type, subtypes, name, signature, ext, _, _, _, _) or
|
||||
barrierModel(namespace, type, subtypes, name, signature, ext, _, _, _, _) or
|
||||
barrierGuardModel(namespace, type, subtypes, name, signature, ext, _, _, _, _, _) or
|
||||
summaryModel(namespace, type, subtypes, name, signature, ext, _, _, _, _, _)
|
||||
}
|
||||
|
||||
@@ -1028,6 +1031,84 @@ private module Cached {
|
||||
isSinkNode(n, kind, model) and n.asNode() = node
|
||||
)
|
||||
}
|
||||
|
||||
private newtype TKindModelPair =
|
||||
TMkPair(string kind, string model) { isBarrierGuardNode(_, _, kind, model) }
|
||||
|
||||
private GuardValue convertAcceptingValue(Public::AcceptingValue av) {
|
||||
av.isTrue() and result.asBooleanValue() = true
|
||||
or
|
||||
av.isFalse() and result.asBooleanValue() = false
|
||||
or
|
||||
// NOTE: The below cases don't contribute anything currently since the
|
||||
// callers immediately use `.asBooleanValue()` to convert the `GuardValue`
|
||||
// to a boolean. Once we're willing to accept the breaking change of
|
||||
// converting the barrier guard API to use `GuardValue`s instead `Boolean`s
|
||||
// we can remove this restriction.
|
||||
av.isNoException() and result.getDualValue().isThrowsException()
|
||||
or
|
||||
av.isZero() and result.asIntValue() = 0
|
||||
or
|
||||
av.isNotZero() and result.getDualValue().asIntValue() = 0
|
||||
or
|
||||
av.isNull() and result.isNullValue()
|
||||
or
|
||||
av.isNotNull() and result.isNonNullValue()
|
||||
}
|
||||
|
||||
private predicate barrierGuardChecks(IRGuardCondition g, Expr e, boolean gv, TKindModelPair kmp) {
|
||||
exists(
|
||||
SourceSinkInterpretationInput::InterpretNode n, Public::AcceptingValue acceptingvalue,
|
||||
string kind, string model
|
||||
|
|
||||
isBarrierGuardNode(n, acceptingvalue, kind, model) and
|
||||
n.asNode().asExpr() = e and
|
||||
kmp = TMkPair(kind, model) and
|
||||
gv = convertAcceptingValue(acceptingvalue).asBooleanValue() and
|
||||
n.asNode().(Private::ArgumentNode).getCall().asCallInstruction() = g
|
||||
)
|
||||
}
|
||||
|
||||
private newtype TKindModelPairIntPair =
|
||||
MkKindModelPairIntPair(TKindModelPair pair, int indirectionIndex) {
|
||||
indirectionIndex > 0 and
|
||||
Private::nodeHasInstruction(_, _, indirectionIndex) and
|
||||
exists(pair)
|
||||
}
|
||||
|
||||
private predicate indirectBarrierGuardChecks(
|
||||
IRGuardCondition g, Expr e, boolean gv, TKindModelPairIntPair kmp
|
||||
) {
|
||||
exists(
|
||||
SourceSinkInterpretationInput::InterpretNode interpretNode,
|
||||
Public::AcceptingValue acceptingvalue, string kind, string model, int indirectionIndex,
|
||||
Private::ArgumentNode arg
|
||||
|
|
||||
isBarrierGuardNode(interpretNode, acceptingvalue, kind, model) and
|
||||
arg = interpretNode.asNode() and
|
||||
arg.asIndirectExpr(indirectionIndex) = e and
|
||||
kmp = MkKindModelPairIntPair(TMkPair(kind, model), indirectionIndex) and
|
||||
gv = convertAcceptingValue(acceptingvalue).asBooleanValue() and
|
||||
arg.getCall().asCallInstruction() = g
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if `node` is specified as a barrier with the given kind in a MaD flow
|
||||
* model.
|
||||
*/
|
||||
cached
|
||||
predicate barrierNode(DataFlow::Node node, string kind, string model) {
|
||||
exists(SourceSinkInterpretationInput::InterpretNode n |
|
||||
isBarrierNode(n, kind, model) and n.asNode() = node
|
||||
)
|
||||
or
|
||||
DataFlow::ParameterizedBarrierGuard<TKindModelPair, barrierGuardChecks/4>::getABarrierNode(TMkPair(kind,
|
||||
model)) = node
|
||||
or
|
||||
DataFlow::ParameterizedBarrierGuard<TKindModelPairIntPair, indirectBarrierGuardChecks/4>::getAnIndirectBarrierNode(MkKindModelPairIntPair(TMkPair(kind,
|
||||
model), _)) = node
|
||||
}
|
||||
}
|
||||
|
||||
import Cached
|
||||
@@ -1044,6 +1125,12 @@ predicate sourceNode(DataFlow::Node node, string kind) { sourceNode(node, kind,
|
||||
*/
|
||||
predicate sinkNode(DataFlow::Node node, string kind) { sinkNode(node, kind, _) }
|
||||
|
||||
/**
|
||||
* Holds if `node` is specified as a barrier with the given kind in a MaD flow
|
||||
* model.
|
||||
*/
|
||||
predicate barrierNode(DataFlow::Node node, string kind) { barrierNode(node, kind, _) }
|
||||
|
||||
private predicate interpretSummary(
|
||||
Function f, string input, string output, string kind, string provenance, string model
|
||||
) {
|
||||
@@ -1058,40 +1145,22 @@ private predicate interpretSummary(
|
||||
|
||||
// adapter class for converting Mad summaries to `SummarizedCallable`s
|
||||
private class SummarizedCallableAdapter extends SummarizedCallable {
|
||||
SummarizedCallableAdapter() { interpretSummary(this, _, _, _, _, _) }
|
||||
string input_;
|
||||
string output_;
|
||||
string kind;
|
||||
Provenance p_;
|
||||
string model_;
|
||||
|
||||
private predicate relevantSummaryElementManual(
|
||||
string input, string output, string kind, string model
|
||||
) {
|
||||
exists(Provenance provenance |
|
||||
interpretSummary(this, input, output, kind, provenance, model) and
|
||||
provenance.isManual()
|
||||
)
|
||||
}
|
||||
|
||||
private predicate relevantSummaryElementGenerated(
|
||||
string input, string output, string kind, string model
|
||||
) {
|
||||
exists(Provenance provenance |
|
||||
interpretSummary(this, input, output, kind, provenance, model) and
|
||||
provenance.isGenerated()
|
||||
)
|
||||
}
|
||||
SummarizedCallableAdapter() { interpretSummary(this, input_, output_, kind, p_, model_) }
|
||||
|
||||
override predicate propagatesFlow(
|
||||
string input, string output, boolean preservesValue, string model
|
||||
string input, string output, boolean preservesValue, Provenance p, boolean isExact, string model
|
||||
) {
|
||||
exists(string kind |
|
||||
this.relevantSummaryElementManual(input, output, kind, model)
|
||||
or
|
||||
not this.relevantSummaryElementManual(_, _, _, _) and
|
||||
this.relevantSummaryElementGenerated(input, output, kind, model)
|
||||
|
|
||||
if kind = "value" then preservesValue = true else preservesValue = false
|
||||
)
|
||||
}
|
||||
|
||||
override predicate hasProvenance(Provenance provenance) {
|
||||
interpretSummary(this, _, _, _, provenance, _)
|
||||
input = input_ and
|
||||
output = output_ and
|
||||
(if kind = "value" then preservesValue = true else preservesValue = false) and
|
||||
p = p_ and
|
||||
isExact = true and
|
||||
model = model_
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,6 +20,8 @@ module Input implements InputSig<Location, DataFlowImplSpecific::CppDataFlow> {
|
||||
|
||||
class SinkBase = Void;
|
||||
|
||||
predicate callableFromSource(SummarizedCallableBase c) { exists(c.getBlock()) }
|
||||
|
||||
ArgumentPosition callbackSelfParameterPosition() { result = TDirectPosition(-1) }
|
||||
|
||||
ReturnKind getStandardReturnValueKind() { result = getReturnValueKind("") }
|
||||
@@ -149,16 +151,27 @@ module SourceSinkInterpretationInput implements
|
||||
}
|
||||
|
||||
predicate barrierElement(
|
||||
Element n, string output, string kind, Public::Provenance provenance, string model
|
||||
Element e, string output, string kind, Public::Provenance provenance, string model
|
||||
) {
|
||||
none()
|
||||
exists(
|
||||
string namespace, string type, boolean subtypes, string name, string signature, string ext
|
||||
|
|
||||
barrierModel(namespace, type, subtypes, name, signature, ext, output, kind, provenance, model) and
|
||||
e = interpretElement(namespace, type, subtypes, name, signature, ext)
|
||||
)
|
||||
}
|
||||
|
||||
predicate barrierGuardElement(
|
||||
Element n, string input, Public::AcceptingValue acceptingvalue, string kind,
|
||||
Element e, string input, Public::AcceptingValue acceptingvalue, string kind,
|
||||
Public::Provenance provenance, string model
|
||||
) {
|
||||
none()
|
||||
exists(
|
||||
string package, string type, boolean subtypes, string name, string signature, string ext
|
||||
|
|
||||
barrierGuardModel(package, type, subtypes, name, signature, ext, input, acceptingvalue, kind,
|
||||
provenance, model) and
|
||||
e = interpretElement(package, type, subtypes, name, signature, ext)
|
||||
)
|
||||
}
|
||||
|
||||
private newtype TInterpretNode =
|
||||
|
||||
@@ -23,7 +23,7 @@ class Expr extends StmtParent, @expr {
|
||||
predicate hasChild(Expr e, int n) { e = this.getChild(n) }
|
||||
|
||||
/** Gets the enclosing function of this expression, if any. */
|
||||
Function getEnclosingFunction() { result = exprEnclosingElement(this) }
|
||||
override Function getEnclosingFunction() { result = exprEnclosingElement(this) }
|
||||
|
||||
/** Gets the nearest enclosing set of curly braces around this expression in the source, if any. */
|
||||
BlockStmt getEnclosingBlock() { result = this.getEnclosingStmt().getEnclosingBlock() }
|
||||
|
||||
@@ -45,13 +45,13 @@ private string getSingleLocationFilePath(@element e) {
|
||||
overlay[local]
|
||||
private string getMultiLocationFilePath(@element e) {
|
||||
exists(@location_default loc |
|
||||
exists(@var_decl vd | var_decls(vd, e, _, _, loc))
|
||||
var_decls(_, e, _, _, loc)
|
||||
or
|
||||
exists(@fun_decl fd | fun_decls(fd, e, _, _, loc))
|
||||
fun_decls(_, e, _, _, loc)
|
||||
or
|
||||
exists(@type_decl td | type_decls(td, e, loc))
|
||||
type_decls(_, e, loc)
|
||||
or
|
||||
exists(@namespace_decl nd | namespace_decls(nd, e, loc, _))
|
||||
namespace_decls(_, e, loc, _)
|
||||
|
|
||||
result = getLocationFilePath(loc)
|
||||
)
|
||||
@@ -62,19 +62,29 @@ private string getMultiLocationFilePath(@element e) {
|
||||
* overlay variant.
|
||||
*/
|
||||
overlay[local]
|
||||
private predicate holdsInBase() { not isOverlay() }
|
||||
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 changed file, or
|
||||
* - All of its locations are in changed files.
|
||||
* - It has a single location in a file extracted in the overlay, or
|
||||
* - All of its locations are in files extracted in the overlay.
|
||||
*/
|
||||
overlay[discard_entity]
|
||||
private predicate discardElement(@element e) {
|
||||
holdsInBase() and
|
||||
isBase() and
|
||||
(
|
||||
overlayChangedFiles(getSingleLocationFilePath(e))
|
||||
overlayHasFile(getSingleLocationFilePath(e))
|
||||
or
|
||||
forex(string path | path = getMultiLocationFilePath(e) | overlayChangedFiles(path))
|
||||
forex(string path | path = getMultiLocationFilePath(e) | overlayHasFile(path))
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1144,7 +1144,7 @@ private newtype TDataFlowCall =
|
||||
}
|
||||
|
||||
private predicate summarizedCallableIsManual(SummarizedCallable sc) {
|
||||
sc.asSummarizedCallable().applyManualModel()
|
||||
sc.asSummarizedCallable().hasManualModel()
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -312,6 +312,13 @@ class Node extends TIRDataFlowNode {
|
||||
*/
|
||||
Expr asDefinition() { result = this.asDefinition(_) }
|
||||
|
||||
private predicate isCertainStore() {
|
||||
exists(SsaImpl::Definition def |
|
||||
SsaImpl::defToNode(this, def, _) and
|
||||
def.isCertain()
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the definition associated with this node, if any.
|
||||
*
|
||||
@@ -361,11 +368,10 @@ class Node extends TIRDataFlowNode {
|
||||
* pointed to by `p`.
|
||||
*/
|
||||
Expr asDefinition(boolean uncertain) {
|
||||
exists(StoreInstruction store, SsaImpl::Definition def |
|
||||
exists(StoreInstruction store |
|
||||
store = this.asInstruction() and
|
||||
result = asDefinitionImpl(store) and
|
||||
SsaImpl::defToNode(this, def, _) and
|
||||
if def.isCertain() then uncertain = false else uncertain = true
|
||||
if this.isCertainStore() then uncertain = false else uncertain = true
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1720,9 +1726,7 @@ private module Cached {
|
||||
SsaImpl::ssaFlow(n, succ) and
|
||||
bb1 = n.getBasicBlock() and
|
||||
bb2 = succ.getBasicBlock() and
|
||||
bb1 != bb2 and
|
||||
bb2.dominates(bb1) and
|
||||
bb1.getASuccessor+() = bb2
|
||||
bb2.strictlyDominates(bb1)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -2417,6 +2421,19 @@ class ContentSet instanceof Content {
|
||||
}
|
||||
}
|
||||
|
||||
private signature class ParamSig;
|
||||
|
||||
private module WithParam<ParamSig P> {
|
||||
/**
|
||||
* Holds if the guard `g` validates the expression `e` upon evaluating to `branch`.
|
||||
*
|
||||
* The expression `e` is expected to be a syntactic part of the guard `g`.
|
||||
* For example, the guard `g` might be a call `isSafe(x)` and the expression `e`
|
||||
* the argument `x`.
|
||||
*/
|
||||
signature predicate guardChecksSig(IRGuardCondition g, Expr e, boolean branch, P param);
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if the guard `g` validates the expression `e` upon evaluating to `branch`.
|
||||
*
|
||||
@@ -2438,7 +2455,7 @@ private predicate controls(IRGuardCondition g, Node n, boolean edge) {
|
||||
* This is expected to be used in `isBarrier`/`isSanitizer` definitions
|
||||
* in data flow and taint tracking.
|
||||
*/
|
||||
module BarrierGuard<guardChecksSig/3 guardChecks> {
|
||||
module ParameterizedBarrierGuard<ParamSig P, WithParam<P>::guardChecksSig/4 guardChecks> {
|
||||
bindingset[value, n]
|
||||
pragma[inline_late]
|
||||
private predicate convertedExprHasValueNumber(ValueNumber value, Node n) {
|
||||
@@ -2448,12 +2465,13 @@ module BarrierGuard<guardChecksSig/3 guardChecks> {
|
||||
)
|
||||
}
|
||||
|
||||
private predicate guardChecksNode(IRGuardCondition g, Node n, boolean branch) {
|
||||
guardChecks(g, n.asOperand().getDef().getConvertedResultExpression(), branch)
|
||||
private predicate guardChecksNode(IRGuardCondition g, Node n, boolean branch, P p) {
|
||||
guardChecks(g, n.asOperand().getDef().getConvertedResultExpression(), branch, p)
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets an expression node that is safely guarded by the given guard check.
|
||||
* Gets an expression node that is safely guarded by the given guard check
|
||||
* when the parameter is `p`.
|
||||
*
|
||||
* For example, given the following code:
|
||||
* ```cpp
|
||||
@@ -2484,19 +2502,27 @@ module BarrierGuard<guardChecksSig/3 guardChecks> {
|
||||
*
|
||||
* NOTE: If an indirect expression is tracked, use `getAnIndirectBarrierNode` instead.
|
||||
*/
|
||||
Node getABarrierNode() {
|
||||
Node getABarrierNode(P p) {
|
||||
exists(IRGuardCondition g, ValueNumber value, boolean edge |
|
||||
convertedExprHasValueNumber(value, result) and
|
||||
guardChecks(g,
|
||||
pragma[only_bind_into](value.getAnInstruction().getConvertedResultExpression()), edge) and
|
||||
pragma[only_bind_into](value.getAnInstruction().getConvertedResultExpression()), edge, p) and
|
||||
controls(g, result, edge)
|
||||
)
|
||||
or
|
||||
result = SsaImpl::BarrierGuard<guardChecksNode/3>::getABarrierNode()
|
||||
result = SsaImpl::BarrierGuard<P, guardChecksNode/4>::getABarrierNode(p)
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets an indirect expression node that is safely guarded by the given guard check.
|
||||
* Gets an expression node that is safely guarded by the given guard check.
|
||||
*
|
||||
* See `getABarrierNode/1` for examples.
|
||||
*/
|
||||
Node getABarrierNode() { result = getABarrierNode(_) }
|
||||
|
||||
/**
|
||||
* Gets an indirect expression node that is safely guarded by the given
|
||||
* guard check with parameter `p`.
|
||||
*
|
||||
* For example, given the following code:
|
||||
* ```cpp
|
||||
@@ -2528,6 +2554,13 @@ module BarrierGuard<guardChecksSig/3 guardChecks> {
|
||||
*
|
||||
* NOTE: If a non-indirect expression is tracked, use `getABarrierNode` instead.
|
||||
*/
|
||||
Node getAnIndirectBarrierNode(P p) { result = getAnIndirectBarrierNode(_, p) }
|
||||
|
||||
/**
|
||||
* Gets an indirect expression node that is safely guarded by the given guard check.
|
||||
*
|
||||
* See `getAnIndirectBarrierNode/1` for examples.
|
||||
*/
|
||||
Node getAnIndirectBarrierNode() { result = getAnIndirectBarrierNode(_) }
|
||||
|
||||
bindingset[value, n]
|
||||
@@ -2542,10 +2575,10 @@ module BarrierGuard<guardChecksSig/3 guardChecks> {
|
||||
}
|
||||
|
||||
private predicate guardChecksIndirectNode(
|
||||
IRGuardCondition g, Node n, boolean branch, int indirectionIndex
|
||||
IRGuardCondition g, Node n, boolean branch, int indirectionIndex, P p
|
||||
) {
|
||||
guardChecks(g, n.asIndirectOperand(indirectionIndex).getDef().getConvertedResultExpression(),
|
||||
branch)
|
||||
branch, p)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -2582,19 +2615,44 @@ module BarrierGuard<guardChecksSig/3 guardChecks> {
|
||||
*
|
||||
* NOTE: If a non-indirect expression is tracked, use `getABarrierNode` instead.
|
||||
*/
|
||||
Node getAnIndirectBarrierNode(int indirectionIndex) {
|
||||
Node getAnIndirectBarrierNode(int indirectionIndex, P p) {
|
||||
exists(IRGuardCondition g, ValueNumber value, boolean edge |
|
||||
indirectConvertedExprHasValueNumber(indirectionIndex, value, result) and
|
||||
guardChecks(g,
|
||||
pragma[only_bind_into](value.getAnInstruction().getConvertedResultExpression()), edge) and
|
||||
pragma[only_bind_into](value.getAnInstruction().getConvertedResultExpression()), edge, p) and
|
||||
controls(g, result, edge)
|
||||
)
|
||||
or
|
||||
result =
|
||||
SsaImpl::BarrierGuardWithIntParam<guardChecksIndirectNode/4>::getABarrierNode(indirectionIndex)
|
||||
SsaImpl::BarrierGuardWithIntParam<P, guardChecksIndirectNode/5>::getABarrierNode(indirectionIndex,
|
||||
p)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides a set of barrier nodes for a guard that validates an expression.
|
||||
*
|
||||
* This is expected to be used in `isBarrier`/`isSanitizer` definitions
|
||||
* in data flow and taint tracking.
|
||||
*/
|
||||
module BarrierGuard<guardChecksSig/3 guardChecks> {
|
||||
private predicate guardChecks(IRGuardCondition g, Expr e, boolean branch, Unit unit) {
|
||||
guardChecks(g, e, branch) and
|
||||
exists(unit)
|
||||
}
|
||||
|
||||
import ParameterizedBarrierGuard<Unit, guardChecks/4>
|
||||
}
|
||||
|
||||
private module InstrWithParam<ParamSig P> {
|
||||
/**
|
||||
* Holds if the guard `g` validates the instruction `instr` upon evaluating to `branch`.
|
||||
*/
|
||||
signature predicate instructionGuardChecksSig(
|
||||
IRGuardCondition g, Instruction instr, boolean branch, P p
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if the guard `g` validates the instruction `instr` upon evaluating to `branch`.
|
||||
*/
|
||||
@@ -2606,7 +2664,9 @@ signature predicate instructionGuardChecksSig(IRGuardCondition g, Instruction in
|
||||
* This is expected to be used in `isBarrier`/`isSanitizer` definitions
|
||||
* in data flow and taint tracking.
|
||||
*/
|
||||
module InstructionBarrierGuard<instructionGuardChecksSig/3 instructionGuardChecks> {
|
||||
module ParameterizedInstructionBarrierGuard<
|
||||
ParamSig P, InstrWithParam<P>::instructionGuardChecksSig/4 instructionGuardChecks>
|
||||
{
|
||||
bindingset[value, n]
|
||||
pragma[inline_late]
|
||||
private predicate operandHasValueNumber(ValueNumber value, Node n) {
|
||||
@@ -2616,21 +2676,27 @@ module InstructionBarrierGuard<instructionGuardChecksSig/3 instructionGuardCheck
|
||||
)
|
||||
}
|
||||
|
||||
private predicate guardChecksNode(IRGuardCondition g, Node n, boolean branch) {
|
||||
instructionGuardChecks(g, n.asOperand().getDef(), branch)
|
||||
private predicate guardChecksNode(IRGuardCondition g, Node n, boolean branch, P p) {
|
||||
instructionGuardChecks(g, n.asOperand().getDef(), branch, p)
|
||||
}
|
||||
|
||||
/** Gets a node that is safely guarded by the given guard check. */
|
||||
Node getABarrierNode() {
|
||||
/**
|
||||
* Gets a node that is safely guarded by the given guard check with
|
||||
* parameter `p`.
|
||||
*/
|
||||
Node getABarrierNode(P p) {
|
||||
exists(IRGuardCondition g, ValueNumber value, boolean edge |
|
||||
instructionGuardChecks(g, pragma[only_bind_into](value.getAnInstruction()), edge) and
|
||||
instructionGuardChecks(g, pragma[only_bind_into](value.getAnInstruction()), edge, p) and
|
||||
operandHasValueNumber(value, result) and
|
||||
controls(g, result, edge)
|
||||
)
|
||||
or
|
||||
result = SsaImpl::BarrierGuard<guardChecksNode/3>::getABarrierNode()
|
||||
result = SsaImpl::BarrierGuard<P, guardChecksNode/4>::getABarrierNode(p)
|
||||
}
|
||||
|
||||
/** Gets a node that is safely guarded by the given guard check. */
|
||||
Node getABarrierNode() { result = getABarrierNode(_) }
|
||||
|
||||
bindingset[value, n]
|
||||
pragma[inline_late]
|
||||
private predicate indirectOperandHasValueNumber(ValueNumber value, int indirectionIndex, Node n) {
|
||||
@@ -2641,25 +2707,52 @@ module InstructionBarrierGuard<instructionGuardChecksSig/3 instructionGuardCheck
|
||||
}
|
||||
|
||||
private predicate guardChecksIndirectNode(
|
||||
IRGuardCondition g, Node n, boolean branch, int indirectionIndex
|
||||
IRGuardCondition g, Node n, boolean branch, int indirectionIndex, P p
|
||||
) {
|
||||
instructionGuardChecks(g, n.asIndirectOperand(indirectionIndex).getDef(), branch)
|
||||
instructionGuardChecks(g, n.asIndirectOperand(indirectionIndex).getDef(), branch, p)
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets an indirect node with indirection index `indirectionIndex` that is
|
||||
* safely guarded by the given guard check.
|
||||
* safely guarded by the given guard check with parameter `p`.
|
||||
*/
|
||||
Node getAnIndirectBarrierNode(int indirectionIndex) {
|
||||
Node getAnIndirectBarrierNode(int indirectionIndex, P p) {
|
||||
exists(IRGuardCondition g, ValueNumber value, boolean edge |
|
||||
instructionGuardChecks(g, pragma[only_bind_into](value.getAnInstruction()), edge) and
|
||||
instructionGuardChecks(g, pragma[only_bind_into](value.getAnInstruction()), edge, p) and
|
||||
indirectOperandHasValueNumber(value, indirectionIndex, result) and
|
||||
controls(g, result, edge)
|
||||
)
|
||||
or
|
||||
result =
|
||||
SsaImpl::BarrierGuardWithIntParam<guardChecksIndirectNode/4>::getABarrierNode(indirectionIndex)
|
||||
SsaImpl::BarrierGuardWithIntParam<P, guardChecksIndirectNode/5>::getABarrierNode(indirectionIndex,
|
||||
p)
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets an indirect node that is safely guarded by the given guard check
|
||||
* with parameter `p`.
|
||||
*/
|
||||
Node getAnIndirectBarrierNode(P p) { result = getAnIndirectBarrierNode(_, p) }
|
||||
|
||||
/** Gets an indirect node that is safely guarded by the given guard check. */
|
||||
Node getAnIndirectBarrierNode() { result = getAnIndirectBarrierNode(_) }
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides a set of barrier nodes for a guard that validates an instruction.
|
||||
*
|
||||
* This is expected to be used in `isBarrier`/`isSanitizer` definitions
|
||||
* in data flow and taint tracking.
|
||||
*/
|
||||
module InstructionBarrierGuard<instructionGuardChecksSig/3 instructionGuardChecks> {
|
||||
private predicate instructionGuardChecks(
|
||||
IRGuardCondition g, Instruction i, boolean branch, Unit unit
|
||||
) {
|
||||
instructionGuardChecks(g, i, branch) and
|
||||
exists(unit)
|
||||
}
|
||||
|
||||
import ParameterizedInstructionBarrierGuard<Unit, instructionGuardChecks/4>
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -15,17 +15,79 @@ private import DataFlowPrivate
|
||||
import SsaImplCommon
|
||||
|
||||
private module SourceVariables {
|
||||
/**
|
||||
* Holds if `store` is the `StoreInstruction` generated by a postfix
|
||||
* increment or decrement operation `e`, and `postCrement` is the operand
|
||||
* that represents the use of the evaluated value of `e`.
|
||||
*/
|
||||
private predicate isUseAfterPostfixCrement0(StoreInstruction store, Operand postCrement) {
|
||||
exists(
|
||||
BinaryInstruction binary, IRBlock b, int iPre, int iPost, int iStore, Operand preCrement,
|
||||
Instruction left
|
||||
|
|
||||
binary instanceof AddInstruction
|
||||
or
|
||||
binary instanceof PointerAddInstruction
|
||||
or
|
||||
binary instanceof SubInstruction
|
||||
or
|
||||
binary instanceof PointerSubInstruction
|
||||
|
|
||||
store.getSourceValue() = binary and
|
||||
left = binary.getLeft() and
|
||||
strictcount(left.getAUse()) = 2 and
|
||||
left.getAUse() = preCrement and
|
||||
left.getAUse() = postCrement and
|
||||
b.getInstruction(iPre) = preCrement.getUse() and
|
||||
b.getInstruction(iPost) = postCrement.getUse() and
|
||||
b.getInstruction(iStore) = store and
|
||||
iPre < iStore and
|
||||
iStore < iPost
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if `store` is the `StoreInstruction` generated by an postfix
|
||||
* increment or decrement operation `e`, and `postCrement` is the fully
|
||||
* converted operand that represents the use of the evaluated value of `e`.
|
||||
*/
|
||||
private predicate isUseAfterPostfixCrement(StoreInstruction store, Operand postCrement) {
|
||||
isUseAfterPostfixCrement0(store, postCrement) and
|
||||
conversionFlow(postCrement, _, false, _)
|
||||
or
|
||||
exists(Instruction instr, Operand postCrement0 |
|
||||
isUseAfterPostfixCrement(store, postCrement0) and
|
||||
conversionFlow(postCrement0, instr, false, _) and
|
||||
instr = postCrement.getDef()
|
||||
)
|
||||
}
|
||||
|
||||
private predicate hasSavedPostfixCrementSourceVariable(
|
||||
BaseSourceVariable base, StoreInstruction store, int ind
|
||||
) {
|
||||
exists(BaseSourceVariableInstruction inst, int ind0 |
|
||||
isUseAfterPostfixCrement(store, _) and
|
||||
inst.getBaseSourceVariable() = base and
|
||||
isDef(_, _, store.getDestinationAddressOperand(), inst, ind0, 0) and
|
||||
ind = [ind0 .. countIndirectionsForCppType(base.getLanguageType()) + 1]
|
||||
)
|
||||
}
|
||||
|
||||
cached
|
||||
private newtype TSourceVariable =
|
||||
TMkSourceVariable(BaseSourceVariable base, int ind) {
|
||||
TNormalSourceVariable(BaseSourceVariable base, int ind) {
|
||||
ind = [0 .. countIndirectionsForCppType(base.getLanguageType()) + 1]
|
||||
} or
|
||||
TSavedPostfixCrementSourceVariable(StoreInstruction store, int ind) {
|
||||
hasSavedPostfixCrementSourceVariable(_, store, ind)
|
||||
}
|
||||
|
||||
class SourceVariable extends TSourceVariable {
|
||||
abstract private class AbstractSourceVariable extends TSourceVariable {
|
||||
BaseSourceVariable base;
|
||||
int ind;
|
||||
|
||||
SourceVariable() { this = TMkSourceVariable(base, ind) }
|
||||
bindingset[ind]
|
||||
AbstractSourceVariable() { any() }
|
||||
|
||||
/** Gets the IR variable associated with this `SourceVariable`, if any. */
|
||||
IRVariable getIRVariable() { result = base.(BaseIRVariable).getIRVariable() }
|
||||
@@ -37,7 +99,7 @@ private module SourceVariables {
|
||||
BaseSourceVariable getBaseVariable() { result = base }
|
||||
|
||||
/** Gets a textual representation of this element. */
|
||||
string toString() { result = repeatStars(this.getIndirection()) + base.toString() }
|
||||
abstract string toString();
|
||||
|
||||
/**
|
||||
* Gets the number of loads performed on the base source variable
|
||||
@@ -62,6 +124,53 @@ private module SourceVariables {
|
||||
/** Gets the location of this variable. */
|
||||
Location getLocation() { result = this.getBaseVariable().getLocation() }
|
||||
}
|
||||
|
||||
final class SourceVariable = AbstractSourceVariable;
|
||||
|
||||
/**
|
||||
* A regular source variable. Most source variables are instances of this
|
||||
* class.
|
||||
*/
|
||||
class NormalSourceVariable extends AbstractSourceVariable, TNormalSourceVariable {
|
||||
NormalSourceVariable() { this = TNormalSourceVariable(base, ind) }
|
||||
|
||||
final override string toString() {
|
||||
result = repeatStars(this.getIndirection()) + base.toString()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Before a value is postfix incremented (or decremented) we "save" its
|
||||
* current value so that the pre-incremented value can be returned to the
|
||||
* enclosing expression. We use the source variables represented by this
|
||||
* class to represent the "saved value".
|
||||
*/
|
||||
class SavedPostfixCrementSourceVariable extends AbstractSourceVariable,
|
||||
TSavedPostfixCrementSourceVariable
|
||||
{
|
||||
StoreInstruction store;
|
||||
|
||||
SavedPostfixCrementSourceVariable() {
|
||||
this = TSavedPostfixCrementSourceVariable(store, ind) and
|
||||
hasSavedPostfixCrementSourceVariable(base, store, ind)
|
||||
}
|
||||
|
||||
final override string toString() {
|
||||
result = repeatStars(this.getIndirection()) + base.toString() + " [before crement]"
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the `StoreInstruction` that writes the incremented (or decremented)
|
||||
* value.
|
||||
*/
|
||||
StoreInstruction getStoreInstruction() { result = store }
|
||||
|
||||
/**
|
||||
* Gets the fully converted `Operand` that represents the use of the
|
||||
* value before the increment.
|
||||
*/
|
||||
Operand getOperand() { isUseAfterPostfixCrement(store, result) }
|
||||
}
|
||||
}
|
||||
|
||||
import SourceVariables
|
||||
@@ -109,17 +218,43 @@ private newtype TDefImpl =
|
||||
TDirectDefImpl(Operand address, int indirectionIndex) {
|
||||
isDef(_, _, address, _, _, indirectionIndex)
|
||||
} or
|
||||
TSavedPostfixCrementDefImpl(SavedPostfixCrementSourceVariable sv, int indirectionIndex) {
|
||||
isDef(_, _, sv.getStoreInstruction().getDestinationAddressOperand(), _, sv.getIndirection(),
|
||||
indirectionIndex)
|
||||
} or
|
||||
TGlobalDefImpl(GlobalLikeVariable v, IRFunction f, int indirectionIndex) {
|
||||
// Represents the initial "definition" of a global variable when entering
|
||||
// a function body.
|
||||
isGlobalDefImpl(v, f, _, indirectionIndex)
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate hasOperandAndIndirection(
|
||||
SavedPostfixCrementSourceVariable sv, Operand operand, int indirection
|
||||
) {
|
||||
sv.getOperand() = operand and
|
||||
sv.getIndirection() = indirection
|
||||
}
|
||||
|
||||
private predicate hasBeforePostCrementUseImpl(
|
||||
SavedPostfixCrementSourceVariable sv, Operand operand, int indirectionIndex
|
||||
) {
|
||||
not isDef(true, _, operand, _, _, _) and
|
||||
exists(int indirection |
|
||||
hasOperandAndIndirection(sv, operand, indirection) and
|
||||
isUse(_, operand, _, indirection, indirectionIndex)
|
||||
)
|
||||
}
|
||||
|
||||
cached
|
||||
private newtype TUseImpl =
|
||||
TDirectUseImpl(Operand operand, int indirectionIndex) {
|
||||
isUse(_, operand, _, _, indirectionIndex) and
|
||||
not isDef(true, _, operand, _, _, _)
|
||||
not isDef(true, _, operand, _, _, _) and
|
||||
not hasBeforePostCrementUseImpl(_, operand, indirectionIndex)
|
||||
} or
|
||||
TSavedPostfixCrementUseImpl(SavedPostfixCrementSourceVariable sv, int indirectionIndex) {
|
||||
hasBeforePostCrementUseImpl(sv, _, indirectionIndex)
|
||||
} or
|
||||
TGlobalUse(GlobalLikeVariable v, IRFunction f, int indirectionIndex) {
|
||||
// Represents a final "use" of a global variable to ensure that
|
||||
@@ -223,19 +358,8 @@ abstract class DefImpl extends TDefImpl {
|
||||
*/
|
||||
abstract int getIndirection();
|
||||
|
||||
/**
|
||||
* Gets the base source variable (i.e., the variable without
|
||||
* any indirection) of this definition or use.
|
||||
*/
|
||||
abstract BaseSourceVariable getBaseSourceVariable();
|
||||
|
||||
/** Gets the variable that is defined or used. */
|
||||
SourceVariable getSourceVariable() {
|
||||
exists(BaseSourceVariable v, int indirection |
|
||||
sourceVariableHasBaseAndIndex(result, v, indirection) and
|
||||
defHasSourceVariable(this, v, indirection)
|
||||
)
|
||||
}
|
||||
abstract SourceVariable getSourceVariable();
|
||||
|
||||
/**
|
||||
* Holds if this definition is guaranteed to totally overwrite the
|
||||
@@ -243,8 +367,8 @@ abstract class DefImpl extends TDefImpl {
|
||||
*/
|
||||
abstract predicate isCertain();
|
||||
|
||||
/** Gets the value written to the destination variable by this definition. */
|
||||
abstract Node0Impl getValue();
|
||||
/** Gets the value written to the destination variable by this definition, if any. */
|
||||
Node0Impl getValue() { none() }
|
||||
|
||||
/** Gets the operand that represents the address of this definition, if any. */
|
||||
Operand getAddressOperand() { none() }
|
||||
@@ -293,19 +417,8 @@ abstract class UseImpl extends TUseImpl {
|
||||
/** Gets the indirection index of this use. */
|
||||
final int getIndirectionIndex() { result = indirectionIndex }
|
||||
|
||||
/**
|
||||
* Gets the base source variable (i.e., the variable without
|
||||
* any indirection) of this definition or use.
|
||||
*/
|
||||
abstract BaseSourceVariable getBaseSourceVariable();
|
||||
|
||||
/** Gets the variable that is defined or used. */
|
||||
SourceVariable getSourceVariable() {
|
||||
exists(BaseSourceVariable v, int indirection |
|
||||
sourceVariableHasBaseAndIndex(result, v, indirection) and
|
||||
useHasSourceVariable(this, v, indirection)
|
||||
)
|
||||
}
|
||||
abstract SourceVariable getSourceVariable();
|
||||
|
||||
/**
|
||||
* Holds if this use is guaranteed to read the
|
||||
@@ -314,18 +427,6 @@ abstract class UseImpl extends TUseImpl {
|
||||
abstract predicate isCertain();
|
||||
}
|
||||
|
||||
pragma[noinline]
|
||||
private predicate defHasSourceVariable(DefImpl def, BaseSourceVariable bv, int ind) {
|
||||
bv = def.getBaseSourceVariable() and
|
||||
ind = def.getIndirection()
|
||||
}
|
||||
|
||||
pragma[noinline]
|
||||
private predicate useHasSourceVariable(UseImpl use, BaseSourceVariable bv, int ind) {
|
||||
bv = use.getBaseSourceVariable() and
|
||||
ind = use.getIndirection()
|
||||
}
|
||||
|
||||
pragma[noinline]
|
||||
private predicate sourceVariableHasBaseAndIndex(SourceVariable v, BaseSourceVariable bv, int ind) {
|
||||
v.getBaseVariable() = bv and
|
||||
@@ -358,16 +459,12 @@ abstract private class DefAddressImpl extends DefImpl, TDefAddressImpl {
|
||||
|
||||
final override predicate isCertain() { any() }
|
||||
|
||||
final override Node0Impl getValue() { none() }
|
||||
|
||||
override Cpp::Location getLocation() { result = v.getLocation() }
|
||||
|
||||
final override SourceVariable getSourceVariable() {
|
||||
final override NormalSourceVariable getSourceVariable() {
|
||||
result.getBaseVariable() = v and
|
||||
result.getIndirection() = 0
|
||||
}
|
||||
|
||||
final override BaseSourceVariable getBaseSourceVariable() { result = v }
|
||||
}
|
||||
|
||||
private class DefVariableAddressImpl extends DefAddressImpl {
|
||||
@@ -413,8 +510,17 @@ private class DirectDef extends DefImpl, TDirectDefImpl {
|
||||
isDef(_, _, address, result, _, indirectionIndex)
|
||||
}
|
||||
|
||||
override BaseSourceVariable getBaseSourceVariable() {
|
||||
result = this.getBase().getBaseSourceVariable()
|
||||
pragma[nomagic]
|
||||
private predicate hasBaseSourceVariableAndIndirection(BaseSourceVariable v, int indirection) {
|
||||
v = this.getBase().getBaseSourceVariable() and
|
||||
indirection = this.getIndirection()
|
||||
}
|
||||
|
||||
final override NormalSourceVariable getSourceVariable() {
|
||||
exists(BaseSourceVariable v, int indirection |
|
||||
sourceVariableHasBaseAndIndex(result, v, indirection) and
|
||||
this.hasBaseSourceVariableAndIndirection(v, indirection)
|
||||
)
|
||||
}
|
||||
|
||||
override int getIndirection() { isDef(_, _, address, _, result, indirectionIndex) }
|
||||
@@ -424,6 +530,32 @@ private class DirectDef extends DefImpl, TDirectDefImpl {
|
||||
override predicate isCertain() { isDef(true, _, address, _, _, indirectionIndex) }
|
||||
}
|
||||
|
||||
/**
|
||||
* A definition that "saves" the value of a variable before it is incremented
|
||||
* or decremented.
|
||||
*/
|
||||
private class SavedPostfixCrementDefImpl extends DefImpl, TSavedPostfixCrementDefImpl {
|
||||
SavedPostfixCrementSourceVariable sv;
|
||||
|
||||
SavedPostfixCrementDefImpl() { this = TSavedPostfixCrementDefImpl(sv, indirectionIndex) }
|
||||
|
||||
override Cpp::Location getLocation() { result = sv.getStoreInstruction().getLocation() }
|
||||
|
||||
final override predicate hasIndexInBlock(IRBlock block, int index) {
|
||||
sv.getStoreInstruction() = block.getInstruction(index)
|
||||
}
|
||||
|
||||
override string toString() { result = "Def of " + this.getSourceVariable() }
|
||||
|
||||
override SourceVariable getSourceVariable() { result = sv }
|
||||
|
||||
override int getIndirection() { result = sv.getIndirection() }
|
||||
|
||||
override predicate isCertain() {
|
||||
isDef(true, _, sv.getStoreInstruction().getDestinationAddressOperand(), _, _, indirectionIndex)
|
||||
}
|
||||
}
|
||||
|
||||
private class DirectUseImpl extends UseImpl, TDirectUseImpl {
|
||||
Operand operand;
|
||||
|
||||
@@ -432,29 +564,22 @@ private class DirectUseImpl extends UseImpl, TDirectUseImpl {
|
||||
override string toString() { result = "Use of " + this.getSourceVariable() }
|
||||
|
||||
final override predicate hasIndexInBlock(IRBlock block, int index) {
|
||||
// See the comment in `ssa0`'s `OperandBasedUse` for an explanation of this
|
||||
// predicate's implementation.
|
||||
if this.getBase().getAst() = any(Cpp::PostfixCrementOperation c).getOperand()
|
||||
then
|
||||
exists(Operand op, int indirection, Instruction base |
|
||||
indirection = this.getIndirection() and
|
||||
base = this.getBase() and
|
||||
op =
|
||||
min(Operand cand, int i |
|
||||
isUse(_, cand, base, indirection, indirectionIndex) and
|
||||
block.getInstruction(i) = cand.getUse()
|
||||
|
|
||||
cand order by i
|
||||
) and
|
||||
block.getInstruction(index) = op.getUse()
|
||||
)
|
||||
else operand.getUse() = block.getInstruction(index)
|
||||
operand.getUse() = block.getInstruction(index)
|
||||
}
|
||||
|
||||
private BaseSourceVariableInstruction getBase() { isUse(_, operand, result, _, indirectionIndex) }
|
||||
|
||||
override BaseSourceVariable getBaseSourceVariable() {
|
||||
result = this.getBase().getBaseSourceVariable()
|
||||
pragma[nomagic]
|
||||
private predicate hasBaseSourceVariableAndIndirection(BaseSourceVariable bv, int indirection) {
|
||||
this.getBase().getBaseSourceVariable() = bv and
|
||||
this.getIndirection() = indirection
|
||||
}
|
||||
|
||||
override NormalSourceVariable getSourceVariable() {
|
||||
exists(BaseSourceVariable v, int indirection |
|
||||
sourceVariableHasBaseAndIndex(result, v, indirection) and
|
||||
this.hasBaseSourceVariableAndIndirection(v, indirection)
|
||||
)
|
||||
}
|
||||
|
||||
final Operand getOperand() { result = operand }
|
||||
@@ -468,6 +593,34 @@ private class DirectUseImpl extends UseImpl, TDirectUseImpl {
|
||||
override Node getNode() { nodeHasOperand(result, operand, indirectionIndex) }
|
||||
}
|
||||
|
||||
/**
|
||||
* The use of the original "saved" variable after the variable has been incremented
|
||||
* or decremented.
|
||||
*/
|
||||
private class SavedPostfixCrementUseImpl extends UseImpl, TSavedPostfixCrementUseImpl {
|
||||
SavedPostfixCrementSourceVariable sv;
|
||||
|
||||
SavedPostfixCrementUseImpl() { this = TSavedPostfixCrementUseImpl(sv, indirectionIndex) }
|
||||
|
||||
override string toString() { result = "Use of " + this.getSourceVariable() }
|
||||
|
||||
final override predicate hasIndexInBlock(IRBlock block, int index) {
|
||||
this.getOperand().getUse() = block.getInstruction(index)
|
||||
}
|
||||
|
||||
override SourceVariable getSourceVariable() { result = sv }
|
||||
|
||||
final Operand getOperand() { result = sv.getOperand() }
|
||||
|
||||
final override Cpp::Location getLocation() { result = this.getOperand().getLocation() }
|
||||
|
||||
override int getIndirection() { result = sv.getIndirection() }
|
||||
|
||||
override predicate isCertain() { isUse(true, this.getOperand(), _, _, indirectionIndex) }
|
||||
|
||||
override Node getNode() { nodeHasOperand(result, this.getOperand(), indirectionIndex) }
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate finalParameterNodeHasParameterAndIndex(
|
||||
FinalParameterNode n, Parameter p, int indirectionIndex
|
||||
@@ -532,7 +685,18 @@ class FinalParameterUse extends UseImpl, TFinalParameterUse {
|
||||
result instanceof UnknownLocation
|
||||
}
|
||||
|
||||
override BaseIRVariable getBaseSourceVariable() { result.getIRVariable().getAst() = p }
|
||||
pragma[nomagic]
|
||||
private predicate hasBaseSourceVariableAndIndirection(BaseIRVariable v, int indirection) {
|
||||
v.getIRVariable().getAst() = p and
|
||||
indirection = this.getIndirection()
|
||||
}
|
||||
|
||||
override NormalSourceVariable getSourceVariable() {
|
||||
exists(BaseIRVariable v, int indirection |
|
||||
sourceVariableHasBaseAndIndex(result, v, indirection) and
|
||||
this.hasBaseSourceVariableAndIndirection(v, indirection)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -612,8 +776,17 @@ class GlobalUse extends UseImpl, TGlobalUse {
|
||||
hasReturnPosition(f, block, index)
|
||||
}
|
||||
|
||||
override BaseSourceVariable getBaseSourceVariable() {
|
||||
baseSourceVariableIsGlobal(result, global, f)
|
||||
pragma[nomagic]
|
||||
private predicate hasBaseSourceVariableAndIndirection(BaseIRVariable v, int indirection) {
|
||||
baseSourceVariableIsGlobal(v, global, f) and
|
||||
indirection = this.getIndirection()
|
||||
}
|
||||
|
||||
override NormalSourceVariable getSourceVariable() {
|
||||
exists(BaseIRVariable v, int indirection |
|
||||
sourceVariableHasBaseAndIndex(result, v, indirection) and
|
||||
this.hasBaseSourceVariableAndIndirection(v, indirection)
|
||||
)
|
||||
}
|
||||
|
||||
final override Cpp::Location getLocation() { result = f.getLocation() }
|
||||
@@ -658,15 +831,15 @@ class GlobalDefImpl extends DefImpl, TGlobalDefImpl {
|
||||
)
|
||||
}
|
||||
|
||||
/** Gets the global variable associated with this definition. */
|
||||
override BaseSourceVariable getBaseSourceVariable() {
|
||||
baseSourceVariableIsGlobal(result, global, f)
|
||||
final override NormalSourceVariable getSourceVariable() {
|
||||
exists(BaseSourceVariable v |
|
||||
sourceVariableHasBaseAndIndex(result, v, indirectionIndex) and
|
||||
baseSourceVariableIsGlobal(v, global, f)
|
||||
)
|
||||
}
|
||||
|
||||
override int getIndirection() { result = indirectionIndex }
|
||||
|
||||
override Node0Impl getValue() { none() }
|
||||
|
||||
override predicate isCertain() { any() }
|
||||
|
||||
/**
|
||||
@@ -704,9 +877,15 @@ predicate defToNode(Node node, Definition def, SourceVariable sv) {
|
||||
}
|
||||
|
||||
private predicate defToNode(Node node, Definition def) {
|
||||
nodeHasOperand(node, def.getValue().asOperand(), def.getIndirectionIndex())
|
||||
or
|
||||
nodeHasInstruction(node, def.getValue().asInstruction(), def.getIndirectionIndex())
|
||||
// Only definitions of `NormalSourceVariable` need to be converted into
|
||||
// dataflow nodes. The other case, `SavedPostfixCrementSourceVariable`,
|
||||
// are internal definitions that don't have a dataflow node representation.
|
||||
def.getSourceVariable() instanceof NormalSourceVariable and
|
||||
(
|
||||
nodeHasOperand(node, def.getValue().asOperand(), def.getIndirectionIndex())
|
||||
or
|
||||
nodeHasInstruction(node, def.getValue().asInstruction(), def.getIndirectionIndex())
|
||||
)
|
||||
or
|
||||
node.(InitialGlobalValue).getGlobalDef() = def
|
||||
}
|
||||
@@ -940,6 +1119,16 @@ module SsaCached {
|
||||
SsaImpl::phiHasInputFromBlock(phi, inp, bb)
|
||||
}
|
||||
|
||||
cached
|
||||
predicate uncertainWriteDefinitionInput(Definition uncertain, Definition inp) {
|
||||
SsaImpl::uncertainWriteDefinitionInput(uncertain, inp)
|
||||
}
|
||||
|
||||
cached
|
||||
predicate ssaDefReachesEndOfBlock(IRBlock bb, Definition def) {
|
||||
SsaImpl::ssaDefReachesEndOfBlock(bb, def, _)
|
||||
}
|
||||
|
||||
predicate variableRead = SsaInput::variableRead/4;
|
||||
|
||||
predicate variableWrite = SsaInput::variableWrite/4;
|
||||
@@ -1035,13 +1224,23 @@ class SynthNode extends DataFlowIntegrationImpl::SsaNode {
|
||||
SynthNode() { not this.asDefinition() instanceof SsaImpl::WriteDefinition }
|
||||
}
|
||||
|
||||
signature predicate guardChecksNodeSig(IRGuards::IRGuardCondition g, Node e, boolean branch);
|
||||
private signature class ParamSig;
|
||||
|
||||
signature predicate guardChecksNodeSig(
|
||||
IRGuards::IRGuardCondition g, Node e, boolean branch, int indirectionIndex
|
||||
);
|
||||
private module ParamIntPair<ParamSig P> {
|
||||
newtype TPair = MkPair(P p, int indirectionIndex) { nodeHasInstruction(_, _, indirectionIndex) }
|
||||
}
|
||||
|
||||
module BarrierGuardWithIntParam<guardChecksNodeSig/4 guardChecksNode> {
|
||||
private module WithParam<ParamSig P> {
|
||||
signature predicate guardChecksNodeSig(IRGuards::IRGuardCondition g, Node e, boolean gv, P param);
|
||||
}
|
||||
|
||||
private module IntWithParam<ParamSig P> {
|
||||
signature predicate guardChecksNodeSig(
|
||||
IRGuards::IRGuardCondition g, Node e, boolean gv, int indirectionIndex, P param
|
||||
);
|
||||
}
|
||||
|
||||
module BarrierGuardWithIntParam<ParamSig P, IntWithParam<P>::guardChecksNodeSig/5 guardChecksNode> {
|
||||
private predicate ssaDefReachesCertainUse(Definition def, UseImpl use) {
|
||||
exists(SourceVariable v, IRBlock bb, int i |
|
||||
use.hasIndexInBlock(bb, i, v) and
|
||||
@@ -1052,21 +1251,23 @@ module BarrierGuardWithIntParam<guardChecksNodeSig/4 guardChecksNode> {
|
||||
|
||||
private predicate guardChecksInstr(
|
||||
IRGuards::Guards_v1::Guard g, IRGuards::GuardsInput::Expr instr, IRGuards::GuardValue gv,
|
||||
int indirectionIndex
|
||||
ParamIntPair<P>::TPair pair
|
||||
) {
|
||||
exists(Node node |
|
||||
exists(Node node, int indirectionIndex, P p |
|
||||
pair = ParamIntPair<P>::MkPair(p, indirectionIndex) and
|
||||
nodeHasInstruction(node, instr, indirectionIndex) and
|
||||
guardChecksNode(g, node, gv.asBooleanValue(), indirectionIndex)
|
||||
guardChecksNode(g, node, gv.asBooleanValue(), indirectionIndex, p)
|
||||
)
|
||||
}
|
||||
|
||||
private predicate guardChecksWithWrappers(
|
||||
DataFlowIntegrationInput::Guard g, SsaImpl::Definition def, IRGuards::GuardValue val,
|
||||
int indirectionIndex
|
||||
ParamIntPair<P>::MkPair pair
|
||||
) {
|
||||
exists(Instruction e |
|
||||
IRGuards::Guards_v1::ParameterizedValidationWrapper<int, guardChecksInstr/4>::guardChecks(g,
|
||||
e, val, indirectionIndex)
|
||||
exists(Instruction e, int indirectionIndex |
|
||||
IRGuards::Guards_v1::ParameterizedValidationWrapper<ParamIntPair<P>::TPair, guardChecksInstr/4>::guardChecks(g,
|
||||
e, val, pair) and
|
||||
pair = ParamIntPair<P>::MkPair(_, indirectionIndex)
|
||||
|
|
||||
indirectionIndex = 0 and
|
||||
def.(Definition).getAUse().getDef() = e
|
||||
@@ -1075,18 +1276,19 @@ module BarrierGuardWithIntParam<guardChecksNodeSig/4 guardChecksNode> {
|
||||
)
|
||||
}
|
||||
|
||||
Node getABarrierNode(int indirectionIndex) {
|
||||
Node getABarrierNode(int indirectionIndex, P p) {
|
||||
// Only get the SynthNodes from the shared implementation, as the ExprNodes cannot
|
||||
// be matched on SourceVariable.
|
||||
result.(SsaSynthNode).getSynthNode() =
|
||||
DataFlowIntegrationImpl::BarrierGuardDefWithState<int, guardChecksWithWrappers/4>::getABarrierNode(indirectionIndex)
|
||||
DataFlowIntegrationImpl::BarrierGuardDefWithState<ParamIntPair<P>::MkPair, guardChecksWithWrappers/4>::getABarrierNode(ParamIntPair<P>::MkPair(p,
|
||||
indirectionIndex))
|
||||
or
|
||||
// Calculate the guarded UseImpls corresponding to ExprNodes directly.
|
||||
exists(
|
||||
DataFlowIntegrationInput::Guard g, IRGuards::GuardValue branch, Definition def, IRBlock bb
|
||||
|
|
||||
guardChecksWithWrappers(g, def, branch, indirectionIndex) and
|
||||
exists(UseImpl use |
|
||||
guardChecksWithWrappers(g, def, branch, ParamIntPair<P>::MkPair(p, indirectionIndex)) and
|
||||
ssaDefReachesCertainUse(def, use) and
|
||||
use.getBlock() = bb and
|
||||
DataFlowIntegrationInput::guardControlsBlock(g, bb, branch) and
|
||||
@@ -1096,15 +1298,16 @@ module BarrierGuardWithIntParam<guardChecksNodeSig/4 guardChecksNode> {
|
||||
}
|
||||
}
|
||||
|
||||
module BarrierGuard<guardChecksNodeSig/3 guardChecksNode> {
|
||||
module BarrierGuard<ParamSig P, WithParam<P>::guardChecksNodeSig/4 guardChecksNode> {
|
||||
private predicate guardChecksNode(
|
||||
IRGuards::IRGuardCondition g, Node e, boolean branch, int indirectionIndex
|
||||
IRGuards::IRGuardCondition g, Node e, boolean gv, int indirectionIndex, P p
|
||||
) {
|
||||
guardChecksNode(g, e, branch) and indirectionIndex = 0
|
||||
indirectionIndex = 0 and
|
||||
guardChecksNode(g, e, gv, p)
|
||||
}
|
||||
|
||||
Node getABarrierNode() {
|
||||
result = BarrierGuardWithIntParam<guardChecksNode/4>::getABarrierNode(0)
|
||||
Node getABarrierNode(P p) {
|
||||
result = BarrierGuardWithIntParam<P, guardChecksNode/5>::getABarrierNode(0, p)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1159,9 +1362,17 @@ class Definition extends SsaImpl::Definition {
|
||||
private Definition getAPhiInputOrPriorDefinition() {
|
||||
result = this.(PhiNode).getAnInput()
|
||||
or
|
||||
SsaImpl::uncertainWriteDefinitionInput(this, result)
|
||||
uncertainWriteDefinitionInput(this, result)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if this SSA definition is live at the end of basic block `bb`.
|
||||
* That is, this definition reaches the end of basic block `bb`, at which
|
||||
* point it is still live, without crossing another SSA definition of the
|
||||
* same source variable.
|
||||
*/
|
||||
predicate isLiveAtEndOfBlock(IRBlock bb) { ssaDefReachesEndOfBlock(bb, this) }
|
||||
|
||||
/**
|
||||
* Gets a definition that ultimately defines this SSA definition and is
|
||||
* not itself a phi node.
|
||||
|
||||
@@ -104,7 +104,11 @@ newtype TInstructionTag =
|
||||
} or
|
||||
SizeofVlaDimensionTag(int index) {
|
||||
exists(VlaDeclStmt v | exists(v.getTransitiveVlaDimensionStmt(index)))
|
||||
}
|
||||
} or
|
||||
AssertionVarAddressTag() or
|
||||
AssertionVarLoadTag() or
|
||||
AssertionOpTag() or
|
||||
AssertionBranchTag()
|
||||
|
||||
class InstructionTag extends TInstructionTag {
|
||||
final string toString() { result = getInstructionTagId(this) }
|
||||
@@ -296,4 +300,12 @@ string getInstructionTagId(TInstructionTag tag) {
|
||||
tag = CoAwaitBranchTag() and result = "CoAwaitBranch"
|
||||
or
|
||||
tag = BoolToIntConversionTag() and result = "BoolToIntConversion"
|
||||
or
|
||||
tag = AssertionVarAddressTag() and result = "AssertionVarAddress"
|
||||
or
|
||||
tag = AssertionVarLoadTag() and result = "AssertionVarLoad"
|
||||
or
|
||||
tag = AssertionOpTag() and result = "AssertionOp"
|
||||
or
|
||||
tag = AssertionBranchTag() and result = "AssertionBranch"
|
||||
}
|
||||
|
||||
@@ -0,0 +1,387 @@
|
||||
private import cpp
|
||||
private import semmle.code.cpp.ir.internal.IRUtilities
|
||||
private import semmle.code.cpp.ir.implementation.internal.OperandTag
|
||||
private import semmle.code.cpp.ir.internal.CppType
|
||||
private import semmle.code.cpp.ir.internal.TempVariableTag
|
||||
private import InstructionTag
|
||||
private import TranslatedElement
|
||||
private import TranslatedStmt
|
||||
private import TranslatedFunction
|
||||
|
||||
/**
|
||||
* Holds if `s` is a statement that may be an expanded assertion in a
|
||||
* release build.
|
||||
*/
|
||||
pragma[nomagic]
|
||||
private predicate stmtCandidate(Stmt s) {
|
||||
not s.isFromUninstantiatedTemplate(_) and
|
||||
(
|
||||
// The expansion of `__analysis_assume(x != 0);` when `__analysis_assume` is
|
||||
// empty is the empty statement.
|
||||
s instanceof EmptyStmt
|
||||
or
|
||||
// The expansion of `assert(x != 0)` when `assert` is `((void)0)` is a zero literal
|
||||
// with a void type.
|
||||
exists(Expr e |
|
||||
e = s.(ExprStmt).getExpr() and
|
||||
e.getValue() = "0" and
|
||||
e.getActualType() instanceof VoidType
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate macroInvocationLocation(int startline, Function f, MacroInvocation mi) {
|
||||
mi.getMacroName() = ["assert", "__analysis_assume"] and
|
||||
mi.getNumberOfArguments() = 1 and
|
||||
mi.getLocation().hasLocationInfo(_, startline, _, _, _) and
|
||||
f.getEntryPoint().isAffectedByMacro(mi)
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate stmtParentLocation(int startline, Function f, StmtParent p) {
|
||||
p.getEnclosingFunction() = f and
|
||||
p.getLocation().hasLocationInfo(_, startline, _, _, _)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if `mi` is a macro invocation with a name that is known
|
||||
* to correspond to an assertion macro, and the macro invocation
|
||||
* is the only thing on the line.
|
||||
*/
|
||||
pragma[nomagic]
|
||||
private predicate assertion0(MacroInvocation mi, Stmt s, string arg) {
|
||||
stmtCandidate(s) and
|
||||
s =
|
||||
unique(StmtParent p, int startline, Function f |
|
||||
macroInvocationLocation(startline, f, mi) and
|
||||
stmtParentLocation(startline, f, p) and
|
||||
// Also do not count the elements from the expanded macro, i.e., when checking
|
||||
// if `assert(x)` is the only thing on the line we do not count the
|
||||
// generated `((void)0)` expression.
|
||||
not p = mi.getAnExpandedElement()
|
||||
|
|
||||
p
|
||||
) and
|
||||
arg = mi.getUnexpandedArgument(0)
|
||||
}
|
||||
|
||||
private Function getEnclosingFunctionForMacroInvocation(MacroInvocation mi) {
|
||||
exists(Stmt s |
|
||||
assertion0(mi, s, _) and
|
||||
result = s.getEnclosingFunction()
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if `arg` has two components and the `i`'th component of the string
|
||||
* `arg` is `s`, and the components are separated by an operation with
|
||||
* opcode `opcode`.
|
||||
*/
|
||||
bindingset[arg]
|
||||
pragma[inline_late]
|
||||
private predicate parseArgument(string arg, string s, int i, Opcode opcode) {
|
||||
s =
|
||||
arg.regexpCapture("([a-zA-Z_][a-zA-Z_0-9]*|[0-9]+)\\s?<=\\s?([a-zA-Z_][a-zA-Z_0-9]*|[0-9]+)",
|
||||
i + 1) and
|
||||
opcode instanceof Opcode::CompareLE
|
||||
or
|
||||
s =
|
||||
arg.regexpCapture("([a-zA-Z_][a-zA-Z_0-9]*|[0-9]+)\\s?>=\\s?([a-zA-Z_][a-zA-Z_0-9]*|[0-9]+)",
|
||||
i + 1) and
|
||||
opcode instanceof Opcode::CompareGE
|
||||
or
|
||||
s =
|
||||
arg.regexpCapture("([a-zA-Z_][a-zA-Z_0-9]*|[0-9]+)\\s?<\\s?([a-zA-Z_][a-zA-Z_0-9]*|[0-9]+)",
|
||||
i + 1) and
|
||||
opcode instanceof Opcode::CompareLT
|
||||
or
|
||||
s =
|
||||
arg.regexpCapture("([a-zA-Z_][a-zA-Z_0-9]*|[0-9]+)\\s?>\\s?([a-zA-Z_][a-zA-Z_0-9]*|[0-9]+)",
|
||||
i + 1) and
|
||||
opcode instanceof Opcode::CompareGT
|
||||
or
|
||||
s =
|
||||
arg.regexpCapture("([a-zA-Z_][a-zA-Z_0-9]*|[0-9]+)\\s?!=\\s?([a-zA-Z_][a-zA-Z_0-9]*|[0-9]+)",
|
||||
i + 1) and
|
||||
opcode instanceof Opcode::CompareNE
|
||||
or
|
||||
s =
|
||||
arg.regexpCapture("([a-zA-Z_][a-zA-Z_0-9]*|[0-9]+)\\s?==\\s?([a-zA-Z_][a-zA-Z_0-9]*|[0-9]+)",
|
||||
i + 1) and
|
||||
opcode instanceof Opcode::CompareEQ
|
||||
}
|
||||
|
||||
private Element getAChildScope(Element scope) { result.getParentScope() = scope }
|
||||
|
||||
private predicate hasAVariable(MacroInvocation mi, Stmt s, Element scope) {
|
||||
assertion0(mi, s, _) and
|
||||
s.getParent() = scope
|
||||
or
|
||||
hasAVariable(mi, s, getAChildScope(scope))
|
||||
}
|
||||
|
||||
private LocalScopeVariable getVariable(MacroInvocation mi, int i) {
|
||||
exists(string operand, string arg, Stmt s |
|
||||
assertion0(mi, s, arg) and
|
||||
parseArgument(arg, operand, i, _) and
|
||||
result =
|
||||
unique(Variable v |
|
||||
v.getLocation().getStartLine() < s.getLocation().getStartLine() and
|
||||
hasAVariable(mi, s, v.getParentScope()) and
|
||||
v.hasName(operand)
|
||||
|
|
||||
v
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if the `i`'th component of the macro invocation `mi` with opcode
|
||||
* `opcode` is a reference to `var`.
|
||||
*/
|
||||
private predicate hasVarAccessMacroArgument(MacroInvocation mi, Variable var, int i, Opcode opcode) {
|
||||
exists(string arg, string s, Function f |
|
||||
arg = mi.getUnexpandedArgument(0) and
|
||||
f = getEnclosingFunctionForMacroInvocation(mi) and
|
||||
parseArgument(arg, s, i, opcode) and
|
||||
var = getVariable(mi, i)
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if the `i`'th component of the macro invocation `mi` with opcode
|
||||
* `opcode` is a constant with the value `k`.
|
||||
*/
|
||||
private predicate hasConstMacroArgument(MacroInvocation mi, int k, int i, Opcode opcode) {
|
||||
exists(string arg, string s |
|
||||
assertion0(mi, _, arg) and
|
||||
s.toInt() = k and
|
||||
parseArgument(arg, s, i, opcode)
|
||||
)
|
||||
}
|
||||
|
||||
predicate hasAssertionOperand(MacroInvocation mi, int i) {
|
||||
hasVarAccessMacroArgument(mi, _, i, _)
|
||||
or
|
||||
hasConstMacroArgument(mi, _, i, _)
|
||||
}
|
||||
|
||||
private predicate hasAssertionOpcode(MacroInvocation mi, Opcode opcode) {
|
||||
hasVarAccessMacroArgument(mi, _, _, opcode)
|
||||
or
|
||||
hasConstMacroArgument(mi, _, _, opcode)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if `mi` is a macro invocation that is an assertion that should be generated
|
||||
* in the control-flow graph at `s`.
|
||||
*/
|
||||
predicate assertion(MacroInvocation mi, Stmt s) {
|
||||
assertion0(mi, s, _) and
|
||||
hasAssertionOperand(mi, 0) and
|
||||
hasAssertionOperand(mi, 1)
|
||||
}
|
||||
|
||||
/** The translation of an operand of an assertion. */
|
||||
abstract private class TranslatedAssertionOperand extends TranslatedElement,
|
||||
TTranslatedAssertionOperand
|
||||
{
|
||||
MacroInvocation mi;
|
||||
int index;
|
||||
|
||||
TranslatedAssertionOperand() { this = TTranslatedAssertionOperand(mi, index) }
|
||||
|
||||
MacroInvocation getMacroInvocation() { result = mi }
|
||||
|
||||
/**
|
||||
* Gets the statement that is being replaced by the assertion that uses this
|
||||
* operand.
|
||||
*/
|
||||
Stmt getStmt() { assertion(mi, result) }
|
||||
|
||||
final override Locatable getAst() { result = this.getStmt() }
|
||||
|
||||
final override TranslatedElement getChild(int id) { none() }
|
||||
|
||||
final override Declaration getFunction() { result = this.getStmt().getEnclosingFunction() }
|
||||
|
||||
/** Gets the instruction which holds the result of this operand. */
|
||||
abstract Instruction getResult();
|
||||
|
||||
final override string toString() { result = "Operand of assertion: " + mi }
|
||||
|
||||
/** Gets the index of this operand (i.e., `0` or `1`). */
|
||||
final int getIndex() { result = index }
|
||||
}
|
||||
|
||||
/** An operand of an assertion that is a variable access. */
|
||||
class TranslatedAssertionVarAccess extends TranslatedAssertionOperand {
|
||||
TranslatedAssertionVarAccess() { hasVarAccessMacroArgument(mi, _, index, _) }
|
||||
|
||||
Variable getVariable() { hasVarAccessMacroArgument(mi, result, index, _) }
|
||||
|
||||
final override IRUserVariable getInstructionVariable(InstructionTag tag) {
|
||||
tag = AssertionVarAddressTag() and
|
||||
result.getVariable() = this.getVariable()
|
||||
}
|
||||
|
||||
final override Instruction getFirstInstruction(EdgeKind kind) {
|
||||
result = this.getInstruction(AssertionVarAddressTag()) and kind instanceof GotoEdge
|
||||
}
|
||||
|
||||
final override Instruction getInstructionSuccessorInternal(InstructionTag tag, EdgeKind kind) {
|
||||
tag = AssertionVarAddressTag() and
|
||||
kind instanceof GotoEdge and
|
||||
result = this.getInstruction(AssertionVarLoadTag())
|
||||
or
|
||||
tag = AssertionVarLoadTag() and
|
||||
result = getTranslatedAssertionMacroInvocation(mi).getChildSuccessor(this, kind)
|
||||
}
|
||||
|
||||
final override Instruction getALastInstructionInternal() {
|
||||
result = this.getInstruction(AssertionVarLoadTag())
|
||||
}
|
||||
|
||||
override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType resultType) {
|
||||
exists(Variable v | v = this.getVariable() |
|
||||
opcode instanceof Opcode::VariableAddress and
|
||||
tag = AssertionVarAddressTag() and
|
||||
resultType = getTypeForGLValue(v.getType())
|
||||
or
|
||||
opcode instanceof Opcode::Load and
|
||||
tag = AssertionVarLoadTag() and
|
||||
resultType = getTypeForPRValue(v.getType())
|
||||
)
|
||||
}
|
||||
|
||||
final override Instruction getInstructionRegisterOperand(InstructionTag tag, OperandTag operandTag) {
|
||||
tag = AssertionVarLoadTag() and
|
||||
operandTag instanceof AddressOperandTag and
|
||||
result = this.getInstruction(AssertionVarAddressTag())
|
||||
}
|
||||
|
||||
final override Instruction getResult() { result = this.getInstruction(AssertionVarLoadTag()) }
|
||||
}
|
||||
|
||||
/** An operand of an assertion that is a constant access. */
|
||||
private class TranslatedAssertionConst extends TranslatedAssertionOperand {
|
||||
TranslatedAssertionConst() { hasConstMacroArgument(mi, _, index, _) }
|
||||
|
||||
int getConst() { hasConstMacroArgument(mi, result, index, _) }
|
||||
|
||||
final override string getInstructionConstantValue(InstructionTag tag) {
|
||||
tag = OnlyInstructionTag() and
|
||||
result = this.getConst().toString()
|
||||
}
|
||||
|
||||
final override Instruction getFirstInstruction(EdgeKind kind) {
|
||||
result = this.getInstruction(OnlyInstructionTag()) and
|
||||
kind instanceof GotoEdge
|
||||
}
|
||||
|
||||
final override Instruction getInstructionSuccessorInternal(InstructionTag tag, EdgeKind kind) {
|
||||
tag = OnlyInstructionTag() and
|
||||
result = getTranslatedAssertionMacroInvocation(mi).getChildSuccessor(this, kind)
|
||||
}
|
||||
|
||||
final override Instruction getALastInstructionInternal() {
|
||||
result = this.getInstruction(OnlyInstructionTag())
|
||||
}
|
||||
|
||||
override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType resultType) {
|
||||
opcode instanceof Opcode::Constant and
|
||||
tag = OnlyInstructionTag() and
|
||||
resultType = getIntType()
|
||||
}
|
||||
|
||||
final override Instruction getResult() { result = this.getInstruction(OnlyInstructionTag()) }
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the `TranslatedAssertionMacroInvocation` corresponding to the macro
|
||||
* invocation `mi`.
|
||||
*/
|
||||
TranslatedAssertionMacroInvocation getTranslatedAssertionMacroInvocation(MacroInvocation mi) {
|
||||
result.getMacroInvocation() = mi
|
||||
}
|
||||
|
||||
/**
|
||||
* A synthesized assertion which would have otherwise been invisible because the
|
||||
* database represents a release build where assertions are disabled.
|
||||
*/
|
||||
private class TranslatedAssertionMacroInvocation extends TranslatedStmt {
|
||||
MacroInvocation mi;
|
||||
|
||||
TranslatedAssertionMacroInvocation() { assertion(mi, stmt) }
|
||||
|
||||
final override Instruction getFirstInstruction(EdgeKind kind) {
|
||||
result = this.getLeft().getFirstInstruction(kind)
|
||||
}
|
||||
|
||||
TranslatedAssertionOperand getLeft() {
|
||||
result.getMacroInvocation() = mi and
|
||||
result.getIndex() = 0
|
||||
}
|
||||
|
||||
TranslatedAssertionOperand getRight() {
|
||||
result.getMacroInvocation() = mi and
|
||||
result.getIndex() = 1
|
||||
}
|
||||
|
||||
final override Instruction getInstructionSuccessorInternal(InstructionTag tag, EdgeKind kind) {
|
||||
tag = AssertionOpTag() and
|
||||
kind instanceof GotoEdge and
|
||||
result = this.getInstruction(AssertionBranchTag())
|
||||
or
|
||||
tag = AssertionBranchTag() and
|
||||
kind instanceof TrueEdge and
|
||||
result = this.getParent().getChildSuccessor(this, _)
|
||||
}
|
||||
|
||||
final override TranslatedElement getChildInternal(int id) {
|
||||
id = 0 and result = this.getLeft()
|
||||
or
|
||||
id = 1 and result = this.getRight()
|
||||
}
|
||||
|
||||
final override Instruction getALastInstructionInternal() {
|
||||
result = this.getInstruction(AssertionBranchTag())
|
||||
}
|
||||
|
||||
final override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType resultType) {
|
||||
tag = AssertionOpTag() and
|
||||
resultType = getBoolType() and
|
||||
hasAssertionOpcode(mi, opcode)
|
||||
or
|
||||
tag = AssertionBranchTag() and
|
||||
resultType = getVoidType() and
|
||||
opcode instanceof Opcode::ConditionalBranch
|
||||
}
|
||||
|
||||
final override Instruction getChildSuccessorInternal(TranslatedElement child, EdgeKind kind) {
|
||||
child = this.getLeft() and
|
||||
result = this.getRight().getFirstInstruction(kind)
|
||||
or
|
||||
child = this.getRight() and
|
||||
kind instanceof GotoEdge and
|
||||
result = this.getInstruction(AssertionOpTag())
|
||||
}
|
||||
|
||||
final override Instruction getInstructionRegisterOperand(InstructionTag tag, OperandTag operandTag) {
|
||||
tag = AssertionOpTag() and
|
||||
(
|
||||
operandTag instanceof LeftOperandTag and
|
||||
result = this.getLeft().getResult()
|
||||
or
|
||||
operandTag instanceof RightOperandTag and
|
||||
result = this.getRight().getResult()
|
||||
)
|
||||
or
|
||||
tag = AssertionBranchTag() and
|
||||
operandTag instanceof ConditionOperandTag and
|
||||
result = this.getInstruction(AssertionOpTag())
|
||||
}
|
||||
|
||||
MacroInvocation getMacroInvocation() { result = mi }
|
||||
}
|
||||
@@ -12,6 +12,7 @@ private import TranslatedFunction
|
||||
private import TranslatedStmt
|
||||
private import TranslatedExpr
|
||||
private import IRConstruction
|
||||
private import TranslatedAssertion
|
||||
private import semmle.code.cpp.models.interfaces.SideEffect
|
||||
private import SideEffects
|
||||
|
||||
@@ -138,6 +139,14 @@ private predicate ignoreExprAndDescendants(Expr expr) {
|
||||
// conditionally constructed (until we have a mechanism for calling these only when the
|
||||
// temporary's constructor was run)
|
||||
isConditionalTemporaryDestructorCall(expr)
|
||||
or
|
||||
// An assertion in a release build is often defined as `#define assert(x) ((void)0)`.
|
||||
// We generate a synthetic assertion in release builds, and when we do that the
|
||||
// expression `((void)0)` should not be translated.
|
||||
exists(MacroInvocation mi |
|
||||
assertion(mi, _) and
|
||||
expr = mi.getExpr().getFullyConverted()
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -909,7 +918,8 @@ newtype TTranslatedElement =
|
||||
} or
|
||||
// The side effect that initializes newly-allocated memory.
|
||||
TTranslatedAllocationSideEffect(AllocationExpr expr) { not ignoreSideEffects(expr) } or
|
||||
TTranslatedStaticStorageDurationVarInit(Variable var) { Raw::varHasIRFunc(var) }
|
||||
TTranslatedStaticStorageDurationVarInit(Variable var) { Raw::varHasIRFunc(var) } or
|
||||
TTranslatedAssertionOperand(MacroInvocation mi, int index) { hasAssertionOperand(mi, index) }
|
||||
|
||||
/**
|
||||
* Gets the index of the first explicitly initialized element in `initList`
|
||||
|
||||
@@ -10,6 +10,7 @@ private import TranslatedElement
|
||||
private import TranslatedExpr
|
||||
private import TranslatedFunction
|
||||
private import TranslatedInitialization
|
||||
private import TranslatedAssertion
|
||||
|
||||
TranslatedStmt getTranslatedStmt(Stmt stmt) { result.getAst() = stmt }
|
||||
|
||||
@@ -324,8 +325,16 @@ abstract class TranslatedStmt extends TranslatedElement, TTranslatedStmt {
|
||||
|
||||
class TranslatedEmptyStmt extends TranslatedStmt {
|
||||
TranslatedEmptyStmt() {
|
||||
stmt instanceof EmptyStmt or
|
||||
stmt instanceof LabelStmt or
|
||||
// An assertion macro invocation can expand to
|
||||
// an empty statement in release builds. In that case
|
||||
// we synthesize the check that would have occurred.
|
||||
// This is handled by `TranslatedAssertion.qll` and so
|
||||
// we exclude these statements here.
|
||||
not assertion(_, stmt) and
|
||||
stmt instanceof EmptyStmt
|
||||
or
|
||||
stmt instanceof LabelStmt
|
||||
or
|
||||
stmt instanceof SwitchCase
|
||||
}
|
||||
|
||||
@@ -381,7 +390,7 @@ class TranslatedDeclStmt extends TranslatedStmt {
|
||||
|
||||
override TranslatedElement getLastChild() { result = this.getChild(this.getChildCount() - 1) }
|
||||
|
||||
private int getChildCount() { result = count(this.getDeclarationEntry(_)) }
|
||||
private int getChildCount() { result = count(int i | exists(this.getDeclarationEntry(i))) }
|
||||
|
||||
IRDeclarationEntry getIRDeclarationEntry(int index) {
|
||||
result.hasIndex(index) and
|
||||
@@ -420,6 +429,15 @@ class TranslatedDeclStmt extends TranslatedStmt {
|
||||
class TranslatedExprStmt extends TranslatedStmt {
|
||||
override ExprStmt stmt;
|
||||
|
||||
TranslatedExprStmt() {
|
||||
// An assertion macro invocation typically expand to the
|
||||
// expression `((void)0)` in release builds. In that case
|
||||
// we synthesize the check that would have occurred.
|
||||
// This is handled by `TranslatedAssertion.qll` and so
|
||||
// we exclude these statements here.
|
||||
not assertion(_, stmt)
|
||||
}
|
||||
|
||||
TranslatedExpr getExpr() { result = getTranslatedExpr(stmt.getExpr().getFullyConverted()) }
|
||||
|
||||
override TranslatedElement getChildInternal(int id) { id = 0 and result = this.getExpr() }
|
||||
|
||||
@@ -57,3 +57,4 @@ private import implementations.CAtlFile
|
||||
private import implementations.CAtlFileMapping
|
||||
private import implementations.CAtlTemporaryFile
|
||||
private import implementations.CRegKey
|
||||
private import implementations.WinHttp
|
||||
|
||||
@@ -16,17 +16,3 @@ private class MySqlExecutionFunction extends SqlExecutionFunction {
|
||||
|
||||
override predicate hasSqlArgument(FunctionInput input) { input.isParameterDeref(1) }
|
||||
}
|
||||
|
||||
/**
|
||||
* The `mysql_real_escape_string` family of functions from the MySQL C API.
|
||||
*/
|
||||
private class MySqlBarrierFunction extends SqlBarrierFunction {
|
||||
MySqlBarrierFunction() {
|
||||
this.hasName(["mysql_real_escape_string", "mysql_real_escape_string_quote"])
|
||||
}
|
||||
|
||||
override predicate barrierSqlArgument(FunctionInput input, FunctionOutput output) {
|
||||
input.isParameterDeref(2) and
|
||||
output.isParameterDeref(1)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,50 @@
|
||||
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 typeBounds(ArithmeticType t, float lb, float ub) {
|
||||
private predicate typeBounds0(ArithmeticType t, float lb, float ub) {
|
||||
exists(IntegralType integralType, float limit |
|
||||
integralType = t and limit = 2.pow(8 * integralType.getSize())
|
||||
|
|
||||
@@ -423,6 +423,42 @@ private predicate typeBounds(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 the in the tests).
|
||||
result = 2.0.pow(40)
|
||||
// specific observed customer databases (and in the tests).
|
||||
result = 2.0.pow(29)
|
||||
}
|
||||
|
||||
/** Gets the maximum number of bounds possible for `t` when widening is used. */
|
||||
|
||||
@@ -20,7 +20,7 @@ class Stmt extends StmtParent, @stmt {
|
||||
predicate hasChild(Element e, int n) { this.getChild(n) = e }
|
||||
|
||||
/** Gets the enclosing function of this statement, if any. */
|
||||
Function getEnclosingFunction() { result = stmtEnclosingElement(this) }
|
||||
override Function getEnclosingFunction() { result = stmtEnclosingElement(this) }
|
||||
|
||||
/**
|
||||
* Gets the nearest enclosing block of this statement in the source, if any.
|
||||
@@ -159,7 +159,10 @@ private class TStmtParent = @stmt or @expr;
|
||||
*
|
||||
* This is normally a statement, but may be a `StmtExpr`.
|
||||
*/
|
||||
class StmtParent extends ControlFlowNode, TStmtParent { }
|
||||
class StmtParent extends ControlFlowNode, TStmtParent {
|
||||
/** Gets the enclosing function of this element, if any. */
|
||||
Function getEnclosingFunction() { none() }
|
||||
}
|
||||
|
||||
/**
|
||||
* A C/C++ 'expression' statement.
|
||||
|
||||
@@ -236,6 +236,34 @@ 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,
|
||||
@@ -2353,6 +2381,7 @@ case @preprocdirect.kind of
|
||||
| 14 = @ppd_ms_import
|
||||
| 15 = @ppd_elifdef
|
||||
| 16 = @ppd_elifndef
|
||||
| 17 = @ppd_embed
|
||||
| 18 = @ppd_warning
|
||||
;
|
||||
|
||||
@@ -2379,6 +2408,11 @@ includes(
|
||||
int included: @file ref
|
||||
);
|
||||
|
||||
embeds(
|
||||
unique int id: @ppd_embed ref,
|
||||
int included: @file ref
|
||||
);
|
||||
|
||||
link_targets(
|
||||
int id: @link_target,
|
||||
int binary: @file ref
|
||||
@@ -2389,6 +2423,8 @@ link_parent(
|
||||
int link_target : @link_target ref
|
||||
);
|
||||
|
||||
/*- Database metadata -*/
|
||||
|
||||
/**
|
||||
* The CLI will automatically emit applicable tuples for this table,
|
||||
* such as `databaseMetadata("isOverlay", "true")` when building an
|
||||
@@ -2399,6 +2435,8 @@ databaseMetadata(
|
||||
string value: string ref
|
||||
);
|
||||
|
||||
/*- Overlay support -*/
|
||||
|
||||
/**
|
||||
* The CLI will automatically emit tuples for each new/modified/deleted file
|
||||
* when building an overlay database.
|
||||
|
||||
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
@@ -0,0 +1,2 @@
|
||||
description: Sections for databaseMetadata and overlayChangedFiles
|
||||
compatibility: full
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,2 @@
|
||||
description: Support embed preprocessor directive
|
||||
compatibility: partial
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,2 @@
|
||||
description: Add trap_filename, source_file_uses_trap and in_trap relations
|
||||
compatibility: full
|
||||
@@ -1,3 +1,11 @@
|
||||
## 1.5.11
|
||||
|
||||
No user-facing changes.
|
||||
|
||||
## 1.5.10
|
||||
|
||||
No user-facing changes.
|
||||
|
||||
## 1.5.9
|
||||
|
||||
### Minor Analysis Improvements
|
||||
|
||||
@@ -45,14 +45,15 @@ module SqlTaintedConfig implements DataFlow::ConfigSig {
|
||||
|
||||
predicate isBarrier(DataFlow::Node node) {
|
||||
node.asExpr().getUnspecifiedType() instanceof IntegralType
|
||||
}
|
||||
|
||||
predicate isBarrierIn(DataFlow::Node node) {
|
||||
or
|
||||
exists(SqlBarrierFunction sql, int arg, FunctionInput input |
|
||||
node.asIndirectArgument() = sql.getACallToThisFunction().getArgument(arg) and
|
||||
input.isParameterDeref(arg) and
|
||||
sql.barrierSqlArgument(input, _)
|
||||
)
|
||||
or
|
||||
// barrier defined using models-as-data
|
||||
barrierNode(node, "sql-injection")
|
||||
}
|
||||
|
||||
predicate observeDiffInformedIncrementalMode() { any() }
|
||||
|
||||
3
cpp/ql/src/change-notes/released/1.5.10.md
Normal file
3
cpp/ql/src/change-notes/released/1.5.10.md
Normal file
@@ -0,0 +1,3 @@
|
||||
## 1.5.10
|
||||
|
||||
No user-facing changes.
|
||||
3
cpp/ql/src/change-notes/released/1.5.11.md
Normal file
3
cpp/ql/src/change-notes/released/1.5.11.md
Normal file
@@ -0,0 +1,3 @@
|
||||
## 1.5.11
|
||||
|
||||
No user-facing changes.
|
||||
@@ -1,2 +1,2 @@
|
||||
---
|
||||
lastReleaseVersion: 1.5.9
|
||||
lastReleaseVersion: 1.5.11
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
name: codeql/cpp-queries
|
||||
version: 1.5.9
|
||||
version: 1.5.11
|
||||
groups:
|
||||
- cpp
|
||||
- queries
|
||||
|
||||
@@ -310,7 +310,7 @@ private module SummaryModelGeneratorInput implements SummaryModelGeneratorInputS
|
||||
}
|
||||
|
||||
private predicate hasManualSummaryModel(Callable api) {
|
||||
api = any(FlowSummaryImpl::Public::SummarizedCallable sc | sc.applyManualModel()) or
|
||||
api = any(FlowSummaryImpl::Public::SummarizedCallable sc | sc.hasManualModel()) or
|
||||
api = any(FlowSummaryImpl::Public::NeutralSummaryCallable sc | sc.hasManualModel())
|
||||
}
|
||||
|
||||
|
||||
@@ -384,7 +384,9 @@ astGuardsControl
|
||||
| test.c:126:7:126:7 | 1 | true | 131 | 132 |
|
||||
| test.c:126:7:126:7 | 1 | true | 134 | 123 |
|
||||
| test.c:126:7:126:28 | ... && ... | true | 126 | 128 |
|
||||
| test.c:126:7:126:28 | ... && ... | true | 131 | 131 |
|
||||
| test.c:126:7:126:28 | ... && ... | true | 131 | 132 |
|
||||
| test.c:126:7:126:28 | ... && ... | true | 134 | 123 |
|
||||
| test.c:126:12:126:26 | call to test3_condition | true | 126 | 128 |
|
||||
| test.c:126:12:126:26 | call to test3_condition | true | 131 | 132 |
|
||||
| test.c:131:7:131:7 | b | true | 131 | 132 |
|
||||
@@ -405,9 +407,7 @@ astGuardsControl
|
||||
| test.c:181:9:181:9 | x | true | 181 | 182 |
|
||||
| test.c:181:9:181:9 | x | true | 186 | 180 |
|
||||
| test.cpp:18:8:18:10 | call to get | true | 19 | 19 |
|
||||
| test.cpp:31:7:31:13 | ... == ... | false | 30 | 30 |
|
||||
| test.cpp:31:7:31:13 | ... == ... | false | 34 | 34 |
|
||||
| test.cpp:31:7:31:13 | ... == ... | true | 30 | 30 |
|
||||
| test.cpp:31:7:31:13 | ... == ... | true | 31 | 32 |
|
||||
| test.cpp:42:13:42:20 | call to getABool | true | 43 | 45 |
|
||||
astGuardsEnsure
|
||||
@@ -589,13 +589,9 @@ astGuardsEnsure
|
||||
| test.c:175:13:175:32 | ... == ... | test.c:175:13:175:15 | call to foo | == | test.c:175:32:175:32 | 0 | 0 | 175 | 175 |
|
||||
| test.c:175:13:175:32 | ... == ... | test.c:175:32:175:32 | 0 | != | test.c:175:13:175:15 | call to foo | 0 | 175 | 175 |
|
||||
| test.c:175:13:175:32 | ... == ... | test.c:175:32:175:32 | 0 | == | test.c:175:13:175:15 | call to foo | 0 | 175 | 175 |
|
||||
| test.cpp:31:7:31:13 | ... == ... | test.cpp:31:7:31:7 | x | != | test.cpp:31:12:31:13 | - ... | 0 | 30 | 30 |
|
||||
| test.cpp:31:7:31:13 | ... == ... | test.cpp:31:7:31:7 | x | != | test.cpp:31:12:31:13 | - ... | 0 | 34 | 34 |
|
||||
| test.cpp:31:7:31:13 | ... == ... | test.cpp:31:7:31:7 | x | == | test.cpp:31:12:31:13 | - ... | 0 | 30 | 30 |
|
||||
| test.cpp:31:7:31:13 | ... == ... | test.cpp:31:7:31:7 | x | == | test.cpp:31:12:31:13 | - ... | 0 | 31 | 32 |
|
||||
| test.cpp:31:7:31:13 | ... == ... | test.cpp:31:12:31:13 | - ... | != | test.cpp:31:7:31:7 | x | 0 | 30 | 30 |
|
||||
| test.cpp:31:7:31:13 | ... == ... | test.cpp:31:12:31:13 | - ... | != | test.cpp:31:7:31:7 | x | 0 | 34 | 34 |
|
||||
| test.cpp:31:7:31:13 | ... == ... | test.cpp:31:12:31:13 | - ... | == | test.cpp:31:7:31:7 | x | 0 | 30 | 30 |
|
||||
| test.cpp:31:7:31:13 | ... == ... | test.cpp:31:12:31:13 | - ... | == | test.cpp:31:7:31:7 | x | 0 | 31 | 32 |
|
||||
astGuardsEnsure_const
|
||||
| test.c:7:9:7:13 | ... > ... | test.c:7:9:7:13 | ... > ... | != | 0 | 7 | 9 |
|
||||
@@ -793,13 +789,21 @@ astGuardsEnsure_const
|
||||
| test.c:126:7:126:7 | 1 | test.c:126:7:126:7 | 1 | == | 1 | 131 | 132 |
|
||||
| test.c:126:7:126:7 | 1 | test.c:126:7:126:7 | 1 | == | 1 | 134 | 123 |
|
||||
| test.c:126:7:126:28 | ... && ... | test.c:126:7:126:7 | 1 | != | 0 | 126 | 128 |
|
||||
| test.c:126:7:126:28 | ... && ... | test.c:126:7:126:7 | 1 | != | 0 | 131 | 131 |
|
||||
| test.c:126:7:126:28 | ... && ... | test.c:126:7:126:7 | 1 | != | 0 | 131 | 132 |
|
||||
| test.c:126:7:126:28 | ... && ... | test.c:126:7:126:7 | 1 | != | 0 | 134 | 123 |
|
||||
| test.c:126:7:126:28 | ... && ... | test.c:126:7:126:7 | 1 | == | 1 | 126 | 128 |
|
||||
| test.c:126:7:126:28 | ... && ... | test.c:126:7:126:7 | 1 | == | 1 | 131 | 131 |
|
||||
| test.c:126:7:126:28 | ... && ... | test.c:126:7:126:7 | 1 | == | 1 | 131 | 132 |
|
||||
| test.c:126:7:126:28 | ... && ... | test.c:126:7:126:7 | 1 | == | 1 | 134 | 123 |
|
||||
| test.c:126:7:126:28 | ... && ... | test.c:126:12:126:26 | call to test3_condition | != | 0 | 126 | 128 |
|
||||
| test.c:126:7:126:28 | ... && ... | test.c:126:12:126:26 | call to test3_condition | != | 0 | 131 | 131 |
|
||||
| test.c:126:7:126:28 | ... && ... | test.c:126:12:126:26 | call to test3_condition | != | 0 | 131 | 132 |
|
||||
| test.c:126:7:126:28 | ... && ... | test.c:126:12:126:26 | call to test3_condition | != | 0 | 134 | 123 |
|
||||
| test.c:126:7:126:28 | ... && ... | test.c:126:12:126:26 | call to test3_condition | == | 1 | 126 | 128 |
|
||||
| test.c:126:7:126:28 | ... && ... | test.c:126:12:126:26 | call to test3_condition | == | 1 | 131 | 131 |
|
||||
| test.c:126:7:126:28 | ... && ... | test.c:126:12:126:26 | call to test3_condition | == | 1 | 131 | 132 |
|
||||
| test.c:126:7:126:28 | ... && ... | test.c:126:12:126:26 | call to test3_condition | == | 1 | 134 | 123 |
|
||||
| test.c:126:12:126:26 | call to test3_condition | test.c:126:12:126:26 | call to test3_condition | != | 0 | 126 | 128 |
|
||||
| test.c:126:12:126:26 | call to test3_condition | test.c:126:12:126:26 | call to test3_condition | != | 0 | 131 | 132 |
|
||||
| test.c:126:12:126:26 | call to test3_condition | test.c:126:12:126:26 | call to test3_condition | == | 1 | 126 | 128 |
|
||||
@@ -846,17 +850,11 @@ astGuardsEnsure_const
|
||||
| test.c:181:9:181:9 | x | test.c:181:9:181:9 | x | == | 1 | 186 | 180 |
|
||||
| test.cpp:18:8:18:10 | call to get | test.cpp:18:8:18:10 | call to get | != | 0 | 19 | 19 |
|
||||
| test.cpp:18:8:18:10 | call to get | test.cpp:18:8:18:10 | call to get | == | 1 | 19 | 19 |
|
||||
| test.cpp:31:7:31:13 | ... == ... | test.cpp:31:7:31:7 | x | != | -1 | 30 | 30 |
|
||||
| test.cpp:31:7:31:13 | ... == ... | test.cpp:31:7:31:7 | x | != | -1 | 34 | 34 |
|
||||
| test.cpp:31:7:31:13 | ... == ... | test.cpp:31:7:31:7 | x | == | -1 | 30 | 30 |
|
||||
| test.cpp:31:7:31:13 | ... == ... | test.cpp:31:7:31:7 | x | == | -1 | 31 | 32 |
|
||||
| test.cpp:31:7:31:13 | ... == ... | test.cpp:31:7:31:13 | ... == ... | != | 0 | 30 | 30 |
|
||||
| test.cpp:31:7:31:13 | ... == ... | test.cpp:31:7:31:13 | ... == ... | != | 0 | 31 | 32 |
|
||||
| test.cpp:31:7:31:13 | ... == ... | test.cpp:31:7:31:13 | ... == ... | != | 1 | 30 | 30 |
|
||||
| test.cpp:31:7:31:13 | ... == ... | test.cpp:31:7:31:13 | ... == ... | != | 1 | 34 | 34 |
|
||||
| test.cpp:31:7:31:13 | ... == ... | test.cpp:31:7:31:13 | ... == ... | == | 0 | 30 | 30 |
|
||||
| test.cpp:31:7:31:13 | ... == ... | test.cpp:31:7:31:13 | ... == ... | == | 0 | 34 | 34 |
|
||||
| test.cpp:31:7:31:13 | ... == ... | test.cpp:31:7:31:13 | ... == ... | == | 1 | 30 | 30 |
|
||||
| test.cpp:31:7:31:13 | ... == ... | test.cpp:31:7:31:13 | ... == ... | == | 1 | 31 | 32 |
|
||||
| test.cpp:42:13:42:20 | call to getABool | test.cpp:42:13:42:20 | call to getABool | != | 0 | 43 | 45 |
|
||||
| test.cpp:42:13:42:20 | call to getABool | test.cpp:42:13:42:20 | call to getABool | == | 1 | 43 | 45 |
|
||||
|
||||
@@ -105,9 +105,13 @@
|
||||
| test.c:126:7:126:7 | 1 | true | test.c:131:10:132:16 | { ... } |
|
||||
| test.c:126:7:126:7 | 1 | true | test.c:134:1:123:10 | return ... |
|
||||
| test.c:126:7:126:28 | ... && ... | not 0 | test.c:126:31:128:16 | { ... } |
|
||||
| test.c:126:7:126:28 | ... && ... | not 0 | test.c:131:3:131:7 | if (...) ... |
|
||||
| test.c:126:7:126:28 | ... && ... | not 0 | test.c:131:10:132:16 | { ... } |
|
||||
| test.c:126:7:126:28 | ... && ... | not 0 | test.c:134:1:123:10 | return ... |
|
||||
| test.c:126:7:126:28 | ... && ... | true | test.c:126:31:128:16 | { ... } |
|
||||
| test.c:126:7:126:28 | ... && ... | true | test.c:131:3:131:7 | if (...) ... |
|
||||
| test.c:126:7:126:28 | ... && ... | true | test.c:131:10:132:16 | { ... } |
|
||||
| test.c:126:7:126:28 | ... && ... | true | test.c:134:1:123:10 | return ... |
|
||||
| test.c:126:12:126:26 | call to test3_condition | not 0 | test.c:126:31:128:16 | { ... } |
|
||||
| test.c:126:12:126:26 | call to test3_condition | not 0 | test.c:131:10:132:16 | { ... } |
|
||||
| test.c:126:12:126:26 | call to test3_condition | true | test.c:126:31:128:16 | { ... } |
|
||||
@@ -162,17 +166,11 @@
|
||||
| test.c:219:9:219:22 | call to __builtin_expect | true | test.c:219:25:221:5 | { ... } |
|
||||
| test.cpp:18:8:18:10 | call to get | not null | test.cpp:19:5:19:14 | ExprStmt |
|
||||
| test.cpp:18:8:18:10 | call to get | true | test.cpp:19:5:19:14 | ExprStmt |
|
||||
| test.cpp:30:22:30:22 | x | -1 | test.cpp:30:6:30:16 | doSomething |
|
||||
| test.cpp:30:22:30:22 | x | -1 | test.cpp:31:16:32:21 | { ... } |
|
||||
| test.cpp:30:22:30:22 | x | not -1 | test.cpp:30:6:30:16 | doSomething |
|
||||
| test.cpp:30:22:30:22 | x | not -1 | test.cpp:34:1:34:1 | return ... |
|
||||
| test.cpp:31:7:31:7 | x | -1 | test.cpp:30:6:30:16 | doSomething |
|
||||
| test.cpp:31:7:31:7 | x | -1 | test.cpp:31:16:32:21 | { ... } |
|
||||
| test.cpp:31:7:31:7 | x | not -1 | test.cpp:30:6:30:16 | doSomething |
|
||||
| test.cpp:31:7:31:7 | x | not -1 | test.cpp:34:1:34:1 | return ... |
|
||||
| test.cpp:31:7:31:13 | ... == ... | false | test.cpp:30:6:30:16 | doSomething |
|
||||
| test.cpp:31:7:31:13 | ... == ... | false | test.cpp:34:1:34:1 | return ... |
|
||||
| test.cpp:31:7:31:13 | ... == ... | true | test.cpp:30:6:30:16 | doSomething |
|
||||
| test.cpp:31:7:31:13 | ... == ... | true | test.cpp:31:16:32:21 | { ... } |
|
||||
| test.cpp:42:13:42:20 | call to getABool | true | test.cpp:43:9:45:23 | { ... } |
|
||||
| test.cpp:60:31:60:31 | i | 0 | test.cpp:62:5:64:12 | case ...: |
|
||||
@@ -408,19 +406,11 @@
|
||||
| test.cpp:400:11:400:25 | call to testEnumWrapper | 2 | test.cpp:404:5:406:12 | case ...: |
|
||||
| test.cpp:400:27:400:27 | b | false | test.cpp:404:5:406:12 | case ...: |
|
||||
| test.cpp:400:27:400:27 | b | true | test.cpp:401:5:403:12 | case ...: |
|
||||
| test.cpp:410:26:410:26 | o | not null | test.cpp:410:6:410:18 | ensureNotNull |
|
||||
| test.cpp:410:26:410:26 | o | not null | test.cpp:412:1:412:1 | return ... |
|
||||
| test.cpp:410:26:410:26 | o | null | test.cpp:410:6:410:18 | ensureNotNull |
|
||||
| test.cpp:410:26:410:26 | o | null | test.cpp:411:11:411:18 | ExprStmt |
|
||||
| test.cpp:411:7:411:8 | ! ... | false | test.cpp:410:6:410:18 | ensureNotNull |
|
||||
| test.cpp:411:7:411:8 | ! ... | false | test.cpp:412:1:412:1 | return ... |
|
||||
| test.cpp:411:7:411:8 | ! ... | true | test.cpp:410:6:410:18 | ensureNotNull |
|
||||
| test.cpp:411:7:411:8 | ! ... | true | test.cpp:411:11:411:18 | ExprStmt |
|
||||
| test.cpp:411:8:411:8 | o | false | test.cpp:410:6:410:18 | ensureNotNull |
|
||||
| test.cpp:411:8:411:8 | o | false | test.cpp:411:11:411:18 | ExprStmt |
|
||||
| test.cpp:411:8:411:8 | o | not null | test.cpp:410:6:410:18 | ensureNotNull |
|
||||
| test.cpp:411:8:411:8 | o | not null | test.cpp:412:1:412:1 | return ... |
|
||||
| test.cpp:411:8:411:8 | o | null | test.cpp:410:6:410:18 | ensureNotNull |
|
||||
| test.cpp:411:8:411:8 | o | null | test.cpp:411:11:411:18 | ExprStmt |
|
||||
| test.cpp:411:8:411:8 | o | true | test.cpp:410:6:410:18 | ensureNotNull |
|
||||
| test.cpp:411:8:411:8 | o | true | test.cpp:412:1:412:1 | return ... |
|
||||
|
||||
@@ -195,13 +195,9 @@ binary
|
||||
| test.c:215:6:215:18 | call to __builtin_expect | test.c:215:17:215:17 | b | < | test.c:215:13:215:13 | a | 0 | test.c:215:21:217:5 | { ... } |
|
||||
| test.c:219:9:219:22 | call to __builtin_expect | test.c:219:16:219:16 | a | >= | test.c:219:20:219:21 | 42 | 1 | test.c:219:25:221:5 | { ... } |
|
||||
| test.c:219:9:219:22 | call to __builtin_expect | test.c:219:20:219:21 | 42 | < | test.c:219:16:219:16 | a | 0 | test.c:219:25:221:5 | { ... } |
|
||||
| test.cpp:31:7:31:13 | ... == ... | test.cpp:31:7:31:7 | x | != | test.cpp:31:12:31:13 | - ... | 0 | test.cpp:30:6:30:16 | doSomething |
|
||||
| test.cpp:31:7:31:13 | ... == ... | test.cpp:31:7:31:7 | x | != | test.cpp:31:12:31:13 | - ... | 0 | test.cpp:34:1:34:1 | return ... |
|
||||
| test.cpp:31:7:31:13 | ... == ... | test.cpp:31:7:31:7 | x | == | test.cpp:31:12:31:13 | - ... | 0 | test.cpp:30:6:30:16 | doSomething |
|
||||
| test.cpp:31:7:31:13 | ... == ... | test.cpp:31:7:31:7 | x | == | test.cpp:31:12:31:13 | - ... | 0 | test.cpp:31:16:32:21 | { ... } |
|
||||
| test.cpp:31:7:31:13 | ... == ... | test.cpp:31:12:31:13 | - ... | != | test.cpp:31:7:31:7 | x | 0 | test.cpp:30:6:30:16 | doSomething |
|
||||
| test.cpp:31:7:31:13 | ... == ... | test.cpp:31:12:31:13 | - ... | != | test.cpp:31:7:31:7 | x | 0 | test.cpp:34:1:34:1 | return ... |
|
||||
| test.cpp:31:7:31:13 | ... == ... | test.cpp:31:12:31:13 | - ... | == | test.cpp:31:7:31:7 | x | 0 | test.cpp:30:6:30:16 | doSomething |
|
||||
| test.cpp:31:7:31:13 | ... == ... | test.cpp:31:12:31:13 | - ... | == | test.cpp:31:7:31:7 | x | 0 | test.cpp:31:16:32:21 | { ... } |
|
||||
| test.cpp:105:6:105:14 | ... != ... | test.cpp:105:6:105:6 | f | != | test.cpp:105:11:105:14 | 0.0 | 0 | test.cpp:105:17:106:7 | { ... } |
|
||||
| test.cpp:105:6:105:14 | ... != ... | test.cpp:105:11:105:14 | 0.0 | != | test.cpp:105:6:105:6 | f | 0 | test.cpp:105:17:106:7 | { ... } |
|
||||
@@ -762,13 +758,21 @@ unary
|
||||
| test.c:126:7:126:7 | 1 | test.c:126:7:126:7 | 1 | == | 1 | test.c:131:10:132:16 | { ... } |
|
||||
| test.c:126:7:126:7 | 1 | test.c:126:7:126:7 | 1 | == | 1 | test.c:134:1:123:10 | return ... |
|
||||
| test.c:126:7:126:28 | ... && ... | test.c:126:7:126:7 | 1 | != | 0 | test.c:126:31:128:16 | { ... } |
|
||||
| test.c:126:7:126:28 | ... && ... | test.c:126:7:126:7 | 1 | != | 0 | test.c:131:3:131:7 | if (...) ... |
|
||||
| test.c:126:7:126:28 | ... && ... | test.c:126:7:126:7 | 1 | != | 0 | test.c:131:10:132:16 | { ... } |
|
||||
| test.c:126:7:126:28 | ... && ... | test.c:126:7:126:7 | 1 | != | 0 | test.c:134:1:123:10 | return ... |
|
||||
| test.c:126:7:126:28 | ... && ... | test.c:126:7:126:7 | 1 | == | 1 | test.c:126:31:128:16 | { ... } |
|
||||
| test.c:126:7:126:28 | ... && ... | test.c:126:7:126:7 | 1 | == | 1 | test.c:131:3:131:7 | if (...) ... |
|
||||
| test.c:126:7:126:28 | ... && ... | test.c:126:7:126:7 | 1 | == | 1 | test.c:131:10:132:16 | { ... } |
|
||||
| test.c:126:7:126:28 | ... && ... | test.c:126:7:126:7 | 1 | == | 1 | test.c:134:1:123:10 | return ... |
|
||||
| test.c:126:7:126:28 | ... && ... | test.c:126:12:126:26 | call to test3_condition | != | 0 | test.c:126:31:128:16 | { ... } |
|
||||
| test.c:126:7:126:28 | ... && ... | test.c:126:12:126:26 | call to test3_condition | != | 0 | test.c:131:3:131:7 | if (...) ... |
|
||||
| test.c:126:7:126:28 | ... && ... | test.c:126:12:126:26 | call to test3_condition | != | 0 | test.c:131:10:132:16 | { ... } |
|
||||
| test.c:126:7:126:28 | ... && ... | test.c:126:12:126:26 | call to test3_condition | != | 0 | test.c:134:1:123:10 | return ... |
|
||||
| test.c:126:7:126:28 | ... && ... | test.c:126:12:126:26 | call to test3_condition | == | 1 | test.c:126:31:128:16 | { ... } |
|
||||
| test.c:126:7:126:28 | ... && ... | test.c:126:12:126:26 | call to test3_condition | == | 1 | test.c:131:3:131:7 | if (...) ... |
|
||||
| test.c:126:7:126:28 | ... && ... | test.c:126:12:126:26 | call to test3_condition | == | 1 | test.c:131:10:132:16 | { ... } |
|
||||
| test.c:126:7:126:28 | ... && ... | test.c:126:12:126:26 | call to test3_condition | == | 1 | test.c:134:1:123:10 | return ... |
|
||||
| test.c:126:12:126:26 | call to test3_condition | test.c:126:12:126:26 | call to test3_condition | != | 0 | test.c:126:31:128:16 | { ... } |
|
||||
| test.c:126:12:126:26 | call to test3_condition | test.c:126:12:126:26 | call to test3_condition | != | 0 | test.c:131:10:132:16 | { ... } |
|
||||
| test.c:126:12:126:26 | call to test3_condition | test.c:126:12:126:26 | call to test3_condition | == | 1 | test.c:126:31:128:16 | { ... } |
|
||||
@@ -853,17 +857,11 @@ unary
|
||||
| test.c:219:9:219:22 | call to __builtin_expect | test.c:219:16:219:21 | ... > ... | != | 0 | test.c:219:25:221:5 | { ... } |
|
||||
| test.cpp:18:8:18:10 | call to get | test.cpp:18:8:18:10 | call to get | != | 0 | test.cpp:19:5:19:14 | ExprStmt |
|
||||
| test.cpp:18:8:18:10 | call to get | test.cpp:18:8:18:10 | call to get | == | 1 | test.cpp:19:5:19:14 | ExprStmt |
|
||||
| test.cpp:31:7:31:13 | ... == ... | test.cpp:31:7:31:7 | x | != | -1 | test.cpp:30:6:30:16 | doSomething |
|
||||
| test.cpp:31:7:31:13 | ... == ... | test.cpp:31:7:31:7 | x | != | -1 | test.cpp:34:1:34:1 | return ... |
|
||||
| test.cpp:31:7:31:13 | ... == ... | test.cpp:31:7:31:7 | x | == | -1 | test.cpp:30:6:30:16 | doSomething |
|
||||
| test.cpp:31:7:31:13 | ... == ... | test.cpp:31:7:31:7 | x | == | -1 | test.cpp:31:16:32:21 | { ... } |
|
||||
| test.cpp:31:7:31:13 | ... == ... | test.cpp:31:7:31:13 | ... == ... | != | 0 | test.cpp:30:6:30:16 | doSomething |
|
||||
| test.cpp:31:7:31:13 | ... == ... | test.cpp:31:7:31:13 | ... == ... | != | 0 | test.cpp:31:16:32:21 | { ... } |
|
||||
| test.cpp:31:7:31:13 | ... == ... | test.cpp:31:7:31:13 | ... == ... | != | 1 | test.cpp:30:6:30:16 | doSomething |
|
||||
| test.cpp:31:7:31:13 | ... == ... | test.cpp:31:7:31:13 | ... == ... | != | 1 | test.cpp:34:1:34:1 | return ... |
|
||||
| test.cpp:31:7:31:13 | ... == ... | test.cpp:31:7:31:13 | ... == ... | == | 0 | test.cpp:30:6:30:16 | doSomething |
|
||||
| test.cpp:31:7:31:13 | ... == ... | test.cpp:31:7:31:13 | ... == ... | == | 0 | test.cpp:34:1:34:1 | return ... |
|
||||
| test.cpp:31:7:31:13 | ... == ... | test.cpp:31:7:31:13 | ... == ... | == | 1 | test.cpp:30:6:30:16 | doSomething |
|
||||
| test.cpp:31:7:31:13 | ... == ... | test.cpp:31:7:31:13 | ... == ... | == | 1 | test.cpp:31:16:32:21 | { ... } |
|
||||
| test.cpp:42:13:42:20 | call to getABool | test.cpp:42:13:42:20 | call to getABool | != | 0 | test.cpp:43:9:45:23 | { ... } |
|
||||
| test.cpp:42:13:42:20 | call to getABool | test.cpp:42:13:42:20 | call to getABool | == | 1 | test.cpp:43:9:45:23 | { ... } |
|
||||
@@ -1401,35 +1399,19 @@ unary
|
||||
| test.cpp:394:7:394:47 | ... == ... | test.cpp:394:15:394:34 | call to returnAIfNoneAreNull | == | 0 | test.cpp:394:50:395:7 | { ... } |
|
||||
| test.cpp:400:11:400:25 | call to testEnumWrapper | test.cpp:400:11:400:25 | call to testEnumWrapper | == | 1 | test.cpp:401:5:403:12 | case ...: |
|
||||
| test.cpp:400:11:400:25 | call to testEnumWrapper | test.cpp:400:11:400:25 | call to testEnumWrapper | == | 2 | test.cpp:404:5:406:12 | case ...: |
|
||||
| test.cpp:411:7:411:8 | ! ... | test.cpp:411:7:411:8 | ! ... | != | 0 | test.cpp:410:6:410:18 | ensureNotNull |
|
||||
| test.cpp:411:7:411:8 | ! ... | test.cpp:411:7:411:8 | ! ... | != | 0 | test.cpp:411:11:411:18 | ExprStmt |
|
||||
| test.cpp:411:7:411:8 | ! ... | test.cpp:411:7:411:8 | ! ... | != | 1 | test.cpp:410:6:410:18 | ensureNotNull |
|
||||
| test.cpp:411:7:411:8 | ! ... | test.cpp:411:7:411:8 | ! ... | != | 1 | test.cpp:412:1:412:1 | return ... |
|
||||
| test.cpp:411:7:411:8 | ! ... | test.cpp:411:7:411:8 | ! ... | == | 0 | test.cpp:410:6:410:18 | ensureNotNull |
|
||||
| test.cpp:411:7:411:8 | ! ... | test.cpp:411:7:411:8 | ! ... | == | 0 | test.cpp:412:1:412:1 | return ... |
|
||||
| test.cpp:411:7:411:8 | ! ... | test.cpp:411:7:411:8 | ! ... | == | 1 | test.cpp:410:6:410:18 | ensureNotNull |
|
||||
| test.cpp:411:7:411:8 | ! ... | test.cpp:411:7:411:8 | ! ... | == | 1 | test.cpp:411:11:411:18 | ExprStmt |
|
||||
| test.cpp:411:7:411:8 | ! ... | test.cpp:411:8:411:8 | o | != | 0 | test.cpp:410:6:410:18 | ensureNotNull |
|
||||
| test.cpp:411:7:411:8 | ! ... | test.cpp:411:8:411:8 | o | != | 0 | test.cpp:412:1:412:1 | return ... |
|
||||
| test.cpp:411:7:411:8 | ! ... | test.cpp:411:8:411:8 | o | != | 1 | test.cpp:410:6:410:18 | ensureNotNull |
|
||||
| test.cpp:411:7:411:8 | ! ... | test.cpp:411:8:411:8 | o | != | 1 | test.cpp:411:11:411:18 | ExprStmt |
|
||||
| test.cpp:411:7:411:8 | ! ... | test.cpp:411:8:411:8 | o | == | 0 | test.cpp:410:6:410:18 | ensureNotNull |
|
||||
| test.cpp:411:7:411:8 | ! ... | test.cpp:411:8:411:8 | o | == | 0 | test.cpp:411:11:411:18 | ExprStmt |
|
||||
| test.cpp:411:7:411:8 | ! ... | test.cpp:411:8:411:8 | o | == | 1 | test.cpp:410:6:410:18 | ensureNotNull |
|
||||
| test.cpp:411:7:411:8 | ! ... | test.cpp:411:8:411:8 | o | == | 1 | test.cpp:412:1:412:1 | return ... |
|
||||
| test.cpp:411:8:411:8 | o | test.cpp:411:7:411:8 | ! ... | != | 0 | test.cpp:410:6:410:18 | ensureNotNull |
|
||||
| test.cpp:411:8:411:8 | o | test.cpp:411:7:411:8 | ! ... | != | 0 | test.cpp:411:11:411:18 | ExprStmt |
|
||||
| test.cpp:411:8:411:8 | o | test.cpp:411:7:411:8 | ! ... | != | 1 | test.cpp:410:6:410:18 | ensureNotNull |
|
||||
| test.cpp:411:8:411:8 | o | test.cpp:411:7:411:8 | ! ... | != | 1 | test.cpp:412:1:412:1 | return ... |
|
||||
| test.cpp:411:8:411:8 | o | test.cpp:411:7:411:8 | ! ... | == | 0 | test.cpp:410:6:410:18 | ensureNotNull |
|
||||
| test.cpp:411:8:411:8 | o | test.cpp:411:7:411:8 | ! ... | == | 0 | test.cpp:412:1:412:1 | return ... |
|
||||
| test.cpp:411:8:411:8 | o | test.cpp:411:7:411:8 | ! ... | == | 1 | test.cpp:410:6:410:18 | ensureNotNull |
|
||||
| test.cpp:411:8:411:8 | o | test.cpp:411:7:411:8 | ! ... | == | 1 | test.cpp:411:11:411:18 | ExprStmt |
|
||||
| test.cpp:411:8:411:8 | o | test.cpp:411:8:411:8 | o | != | 0 | test.cpp:410:6:410:18 | ensureNotNull |
|
||||
| test.cpp:411:8:411:8 | o | test.cpp:411:8:411:8 | o | != | 0 | test.cpp:412:1:412:1 | return ... |
|
||||
| test.cpp:411:8:411:8 | o | test.cpp:411:8:411:8 | o | != | 1 | test.cpp:410:6:410:18 | ensureNotNull |
|
||||
| test.cpp:411:8:411:8 | o | test.cpp:411:8:411:8 | o | != | 1 | test.cpp:411:11:411:18 | ExprStmt |
|
||||
| test.cpp:411:8:411:8 | o | test.cpp:411:8:411:8 | o | == | 0 | test.cpp:410:6:410:18 | ensureNotNull |
|
||||
| test.cpp:411:8:411:8 | o | test.cpp:411:8:411:8 | o | == | 0 | test.cpp:411:11:411:18 | ExprStmt |
|
||||
| test.cpp:411:8:411:8 | o | test.cpp:411:8:411:8 | o | == | 1 | test.cpp:410:6:410:18 | ensureNotNull |
|
||||
| test.cpp:411:8:411:8 | o | test.cpp:411:8:411:8 | o | == | 1 | test.cpp:412:1:412:1 | return ... |
|
||||
|
||||
18
cpp/ql/test/library-tests/dataflow/asDefinition/test.cpp
Normal file
18
cpp/ql/test/library-tests/dataflow/asDefinition/test.cpp
Normal file
@@ -0,0 +1,18 @@
|
||||
struct S {
|
||||
int x;
|
||||
};
|
||||
|
||||
void use(int);
|
||||
|
||||
void test() {
|
||||
int y = 43; // $ asDefinition=43
|
||||
use(y);
|
||||
y = 44; // $ asDefinition="... = ..."
|
||||
use(y);
|
||||
|
||||
int x = 43; // $ asDefinition=43
|
||||
x = 44; // $ asDefinition="... = ..."
|
||||
|
||||
S s;
|
||||
s.x = 42; // $ asDefinition="... = ..."
|
||||
}
|
||||
22
cpp/ql/test/library-tests/dataflow/asDefinition/test.ql
Normal file
22
cpp/ql/test/library-tests/dataflow/asDefinition/test.ql
Normal file
@@ -0,0 +1,22 @@
|
||||
import cpp
|
||||
import utils.test.InlineExpectationsTest
|
||||
import semmle.code.cpp.dataflow.new.DataFlow::DataFlow
|
||||
|
||||
bindingset[s]
|
||||
string quote(string s) { if s.matches("% %") then result = "\"" + s + "\"" else result = s }
|
||||
|
||||
module AsDefinitionTest implements TestSig {
|
||||
string getARelevantTag() { result = "asDefinition" }
|
||||
|
||||
predicate hasActualResult(Location location, string element, string tag, string value) {
|
||||
exists(Node n, Expr e |
|
||||
e = n.asDefinition() and
|
||||
location = e.getLocation() and
|
||||
element = n.toString() and
|
||||
tag = "asDefinition" and
|
||||
value = quote(e.toString())
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
import MakeTest<AsDefinitionTest>
|
||||
@@ -147,6 +147,29 @@ astFlow
|
||||
| test.cpp:1165:10:1165:15 | call to source | test.cpp:1239:10:1239:26 | * ... |
|
||||
| test.cpp:1195:10:1195:24 | call to indirect_source | test.cpp:1200:19:1200:36 | global_int_ptr_ptr |
|
||||
| test.cpp:1195:10:1195:24 | call to indirect_source | test.cpp:1201:10:1201:27 | global_int_ptr_ptr |
|
||||
| test.cpp:1258:11:1258:16 | call to source | test.cpp:1259:8:1259:10 | ... ++ |
|
||||
| test.cpp:1262:7:1262:12 | call to source | test.cpp:1263:8:1263:10 | ... -- |
|
||||
| test.cpp:1266:7:1266:12 | call to source | test.cpp:1267:8:1267:10 | ++ ... |
|
||||
| test.cpp:1266:7:1266:12 | call to source | test.cpp:1268:8:1268:8 | x |
|
||||
| test.cpp:1270:7:1270:12 | call to source | test.cpp:1271:8:1271:10 | -- ... |
|
||||
| test.cpp:1270:7:1270:12 | call to source | test.cpp:1272:8:1272:8 | x |
|
||||
| test.cpp:1274:7:1274:12 | call to source | test.cpp:1275:8:1275:14 | ... += ... |
|
||||
| test.cpp:1274:7:1274:12 | call to source | test.cpp:1276:8:1276:8 | x |
|
||||
| test.cpp:1278:7:1278:12 | call to source | test.cpp:1279:8:1279:14 | ... -= ... |
|
||||
| test.cpp:1278:7:1278:12 | call to source | test.cpp:1280:8:1280:8 | x |
|
||||
| test.cpp:1284:11:1284:16 | call to source | test.cpp:1285:8:1285:20 | ... ? ... : ... |
|
||||
| test.cpp:1288:7:1288:12 | call to source | test.cpp:1289:8:1289:20 | ... ++ |
|
||||
| test.cpp:1288:7:1288:12 | call to source | test.cpp:1290:8:1290:8 | x |
|
||||
| test.cpp:1292:7:1292:12 | call to source | test.cpp:1294:8:1294:8 | x |
|
||||
| test.cpp:1296:7:1296:12 | call to source | test.cpp:1297:8:1297:18 | ... ? ... : ... |
|
||||
| test.cpp:1296:7:1296:12 | call to source | test.cpp:1298:8:1298:8 | x |
|
||||
| test.cpp:1300:7:1300:12 | call to source | test.cpp:1301:8:1301:18 | ... ? ... : ... |
|
||||
| test.cpp:1300:7:1300:12 | call to source | test.cpp:1302:8:1302:8 | x |
|
||||
| test.cpp:1304:7:1304:12 | call to source | test.cpp:1305:8:1305:18 | ... ? ... : ... |
|
||||
| test.cpp:1304:7:1304:12 | call to source | test.cpp:1306:8:1306:8 | x |
|
||||
| test.cpp:1308:7:1308:12 | call to source | test.cpp:1309:14:1309:16 | ... ++ |
|
||||
| test.cpp:1312:7:1312:12 | call to source | test.cpp:1313:8:1313:24 | ... ? ... : ... |
|
||||
| test.cpp:1312:7:1312:12 | call to source | test.cpp:1314:8:1314:8 | x |
|
||||
| true_upon_entry.cpp:17:11:17:16 | call to source | true_upon_entry.cpp:21:8:21:8 | x |
|
||||
| true_upon_entry.cpp:27:9:27:14 | call to source | true_upon_entry.cpp:29:8:29:8 | x |
|
||||
| true_upon_entry.cpp:33:11:33:16 | call to source | true_upon_entry.cpp:39:8:39:8 | x |
|
||||
@@ -354,6 +377,19 @@ irFlow
|
||||
| test.cpp:1195:10:1195:24 | *call to indirect_source | test.cpp:1218:19:1218:36 | **global_int_ptr_ptr |
|
||||
| test.cpp:1195:10:1195:24 | *call to indirect_source | test.cpp:1224:19:1224:37 | ** ... |
|
||||
| test.cpp:1195:10:1195:24 | *call to indirect_source | test.cpp:1227:10:1227:29 | * ... |
|
||||
| test.cpp:1258:11:1258:16 | call to source | test.cpp:1259:8:1259:10 | ... ++ |
|
||||
| test.cpp:1262:7:1262:12 | call to source | test.cpp:1263:8:1263:10 | ... -- |
|
||||
| test.cpp:1284:11:1284:16 | call to source | test.cpp:1285:8:1285:20 | ... ? ... : ... |
|
||||
| test.cpp:1288:7:1288:12 | call to source | test.cpp:1290:8:1290:8 | x |
|
||||
| test.cpp:1292:7:1292:12 | call to source | test.cpp:1294:8:1294:8 | x |
|
||||
| test.cpp:1296:7:1296:12 | call to source | test.cpp:1297:8:1297:18 | ... ? ... : ... |
|
||||
| test.cpp:1296:7:1296:12 | call to source | test.cpp:1298:8:1298:8 | x |
|
||||
| test.cpp:1300:7:1300:12 | call to source | test.cpp:1301:8:1301:18 | ... ? ... : ... |
|
||||
| test.cpp:1300:7:1300:12 | call to source | test.cpp:1302:8:1302:8 | x |
|
||||
| test.cpp:1304:7:1304:12 | call to source | test.cpp:1306:8:1306:8 | x |
|
||||
| test.cpp:1308:7:1308:12 | call to source | test.cpp:1309:8:1309:16 | ... ++ |
|
||||
| test.cpp:1312:7:1312:12 | call to source | test.cpp:1313:8:1313:24 | ... ? ... : ... |
|
||||
| test.cpp:1312:7:1312:12 | call to source | test.cpp:1314:8:1314:8 | x |
|
||||
| true_upon_entry.cpp:9:11:9:16 | call to source | true_upon_entry.cpp:13:8:13:8 | x |
|
||||
| true_upon_entry.cpp:17:11:17:16 | call to source | true_upon_entry.cpp:21:8:21:8 | x |
|
||||
| true_upon_entry.cpp:27:9:27:14 | call to source | true_upon_entry.cpp:29:8:29:8 | x |
|
||||
|
||||
@@ -1252,4 +1252,64 @@ namespace globals_without_explicit_def {
|
||||
calls_set_array();
|
||||
sink(*global_int_array); // $ ir MISSING: ast
|
||||
}
|
||||
}
|
||||
|
||||
void crement_test1() {
|
||||
int x = source();
|
||||
sink(x++); // $ ir ast
|
||||
sink(x);
|
||||
|
||||
x = source();
|
||||
sink(x--); // $ ir ast
|
||||
sink(x);
|
||||
|
||||
x = source();
|
||||
sink(++x); // $ SPURIOUS: ast
|
||||
sink(x); // $ SPURIOUS: ast
|
||||
|
||||
x = source();
|
||||
sink(--x); // $ SPURIOUS: ast
|
||||
sink(x); // $ SPURIOUS: ast
|
||||
|
||||
x = source();
|
||||
sink(x += 10); // $ SPURIOUS: ast
|
||||
sink(x); // $ SPURIOUS: ast
|
||||
|
||||
x = source();
|
||||
sink(x -= 10); // $ SPURIOUS: ast
|
||||
sink(x); // $ SPURIOUS: ast
|
||||
}
|
||||
|
||||
void crement_test2(bool b, int y) {
|
||||
int x = source();
|
||||
sink(b ? x++ : x--); // $ ir ast
|
||||
sink(x);
|
||||
|
||||
x = source();
|
||||
sink((b ? x : y)++); // $ ast MISSING: ir
|
||||
sink(x); // $ ir ast
|
||||
|
||||
x = source();
|
||||
sink(++(b ? x : y));
|
||||
sink(x); // $ ir ast
|
||||
|
||||
x = source();
|
||||
sink(b ? x++ : y); // $ ir ast
|
||||
sink(x); // $ ir ast
|
||||
|
||||
x = source();
|
||||
sink(b ? x : y++); // $ ir ast
|
||||
sink(x); // $ ir ast
|
||||
|
||||
x = source();
|
||||
sink(b ? ++x : y); // $ SPURIOUS: ast
|
||||
sink(x); // $ ir ast
|
||||
|
||||
x = source();
|
||||
sink((long)x++); // $ ir ast
|
||||
sink(x);
|
||||
|
||||
x = source();
|
||||
sink(b ? (long)x++ : 0); // $ ir ast
|
||||
sink(x); // $ ir ast
|
||||
}
|
||||
297
cpp/ql/test/library-tests/dataflow/external-models/azure.cpp
Normal file
297
cpp/ql/test/library-tests/dataflow/external-models/azure.cpp
Normal file
@@ -0,0 +1,297 @@
|
||||
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
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user