mirror of
https://github.com/github/codeql.git
synced 2026-05-17 20:57:07 +02:00
Compare commits
520 Commits
rdmarsh2/c
...
aeisenberg
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a065974fb8 | ||
|
|
059d32089e | ||
|
|
bc17d061e7 | ||
|
|
e174123c43 | ||
|
|
ddeae090a3 | ||
|
|
bf6e988fcd | ||
|
|
6b2ebcce3a | ||
|
|
159ee99b6d | ||
|
|
3410dd589d | ||
|
|
5c37430031 | ||
|
|
89fc84d29a | ||
|
|
6bee9d8dee | ||
|
|
67f8c8215c | ||
|
|
b4b52b9074 | ||
|
|
4a8d08e21f | ||
|
|
2a529cf385 | ||
|
|
95a9faf1f9 | ||
|
|
b1e0d73de8 | ||
|
|
987870bb62 | ||
|
|
6f4806361b | ||
|
|
65c2477409 | ||
|
|
3f7a34de94 | ||
|
|
137b068e4c | ||
|
|
9e6e37a223 | ||
|
|
0cc3b8a9ec | ||
|
|
8a5cb11014 | ||
|
|
4a8960607d | ||
|
|
bd5eb1f0ac | ||
|
|
d18d5b5cf4 | ||
|
|
3bb7e28712 | ||
|
|
5c3d6cedfa | ||
|
|
ff731f1d83 | ||
|
|
c0dd9dd5d5 | ||
|
|
b84dca92cf | ||
|
|
d1867b9716 | ||
|
|
e8864d072d | ||
|
|
95c60858d4 | ||
|
|
f448965953 | ||
|
|
6ffaa6918a | ||
|
|
bc57d87303 | ||
|
|
0353b3ebfc | ||
|
|
57f50725ba | ||
|
|
bbf4563cfe | ||
|
|
b2c38b37de | ||
|
|
66df44f8c9 | ||
|
|
8b8a662c76 | ||
|
|
c76b6d1782 | ||
|
|
810568cf02 | ||
|
|
b94e0d3e69 | ||
|
|
eff3747eb9 | ||
|
|
07457b2b5f | ||
|
|
d708abfc80 | ||
|
|
c9cd809ef2 | ||
|
|
e979dffc08 | ||
|
|
985e87ccde | ||
|
|
0e3d520712 | ||
|
|
98db1af898 | ||
|
|
fd4f60dd1b | ||
|
|
ebd97f4496 | ||
|
|
0776687991 | ||
|
|
6674e07eaa | ||
|
|
12015928c1 | ||
|
|
5ef69628b3 | ||
|
|
f07e0592d0 | ||
|
|
c7c3ad29cd | ||
|
|
2cbba65617 | ||
|
|
62986a23f3 | ||
|
|
afd00161e8 | ||
|
|
b99e9a58e7 | ||
|
|
9fd9a04c2f | ||
|
|
5f841f71db | ||
|
|
604af4f7b3 | ||
|
|
e8d13d156d | ||
|
|
cec63e4522 | ||
|
|
aa539454b5 | ||
|
|
b2431d0b50 | ||
|
|
1178dcb507 | ||
|
|
b77d77d8eb | ||
|
|
1c21ce0ec4 | ||
|
|
6a90db9b30 | ||
|
|
b38ad13f82 | ||
|
|
c19574b9a4 | ||
|
|
b197eff23e | ||
|
|
ab22f932a5 | ||
|
|
1fe9b3f4bd | ||
|
|
e680d1a6ec | ||
|
|
0de0325c8e | ||
|
|
38ba516687 | ||
|
|
824ac9eb73 | ||
|
|
e1a153a7f3 | ||
|
|
43a553dffb | ||
|
|
674305195a | ||
|
|
d50e3c77e5 | ||
|
|
c239871f3a | ||
|
|
14dafefb79 | ||
|
|
2cacba5f66 | ||
|
|
d8b352c2e6 | ||
|
|
6f7f760682 | ||
|
|
608f99bd0d | ||
|
|
634e883221 | ||
|
|
bb5f0d4afb | ||
|
|
81cf4c39f4 | ||
|
|
623ba7926f | ||
|
|
f22de8a3b7 | ||
|
|
56bbba2241 | ||
|
|
62383fb3c9 | ||
|
|
296aa52ef0 | ||
|
|
55fdf84d15 | ||
|
|
c9ba6f171b | ||
|
|
9a7d74f2ba | ||
|
|
94a6506cbb | ||
|
|
93ade495c2 | ||
|
|
353b50b0d3 | ||
|
|
98436ce36a | ||
|
|
a14efcfb69 | ||
|
|
e96e965bf9 | ||
|
|
361ddb844e | ||
|
|
5b528573ce | ||
|
|
c3a8da4570 | ||
|
|
b471b51535 | ||
|
|
a4d1b33993 | ||
|
|
0ee72a580a | ||
|
|
a35c7ab5b3 | ||
|
|
7daf53fd99 | ||
|
|
2ecd9c93d1 | ||
|
|
48761b8667 | ||
|
|
2138e491a5 | ||
|
|
8c5d220dc0 | ||
|
|
5004a5fb60 | ||
|
|
09e62058ae | ||
|
|
9fad42b25d | ||
|
|
bb82bcabbe | ||
|
|
8c7fdb969d | ||
|
|
a144fa06dc | ||
|
|
57d861337b | ||
|
|
2234070bfe | ||
|
|
3d0d3ecfca | ||
|
|
6d5d78e975 | ||
|
|
c842ae40f6 | ||
|
|
e3e9774956 | ||
|
|
089ce5a8a4 | ||
|
|
c339a2d4a7 | ||
|
|
ed04bec34e | ||
|
|
99d9fe14c8 | ||
|
|
3195404b63 | ||
|
|
7c12139c9e | ||
|
|
3646d1d294 | ||
|
|
a56876533f | ||
|
|
db1661fb13 | ||
|
|
3eab35d78b | ||
|
|
07b3b15528 | ||
|
|
6a4b748958 | ||
|
|
4f7eb7be83 | ||
|
|
b05d8a61ba | ||
|
|
c77f573a8e | ||
|
|
46c52aeaae | ||
|
|
2c584d8f35 | ||
|
|
bea0ce9ff9 | ||
|
|
6cee635cb5 | ||
|
|
7584434b80 | ||
|
|
1d2d28be76 | ||
|
|
9d3bc47a4d | ||
|
|
ddb7bb11fd | ||
|
|
2223bc3d1f | ||
|
|
ae9ba80c40 | ||
|
|
3c3390728a | ||
|
|
710ba3cb14 | ||
|
|
8f332714f4 | ||
|
|
a65e585db1 | ||
|
|
e4d22a2a5a | ||
|
|
e66d2dddb6 | ||
|
|
c65ae88c6d | ||
|
|
8d0ca9c772 | ||
|
|
d577392dee | ||
|
|
6576f19873 | ||
|
|
00c55092ee | ||
|
|
4f63317369 | ||
|
|
7ed18f1b32 | ||
|
|
cc1a5d82b8 | ||
|
|
70cabf188e | ||
|
|
c30f39df33 | ||
|
|
f956999891 | ||
|
|
aad77c2388 | ||
|
|
8ff0a191be | ||
|
|
a5415c9c8a | ||
|
|
afeea64078 | ||
|
|
4d485163a6 | ||
|
|
96752f0fc4 | ||
|
|
e294b8f74a | ||
|
|
d3250a7e16 | ||
|
|
04c230b128 | ||
|
|
92a927efa7 | ||
|
|
5d9f366ac5 | ||
|
|
bee4e4b40a | ||
|
|
d5200efef3 | ||
|
|
efcd47f114 | ||
|
|
c8441abaac | ||
|
|
9d456e0436 | ||
|
|
6240b6e699 | ||
|
|
e4ff25099b | ||
|
|
d98d1b7455 | ||
|
|
86034dc602 | ||
|
|
129ed426a0 | ||
|
|
c0bc0d78cc | ||
|
|
7dc5bdafe3 | ||
|
|
c8deb72ede | ||
|
|
74cd532adc | ||
|
|
60fad4d652 | ||
|
|
f5a30c7bbe | ||
|
|
38f185bee4 | ||
|
|
18b5ab0862 | ||
|
|
c75c489707 | ||
|
|
914b9680c0 | ||
|
|
eca28af883 | ||
|
|
be88c4f171 | ||
|
|
6d00860cc1 | ||
|
|
0729e42536 | ||
|
|
bf7437fd2e | ||
|
|
122433096d | ||
|
|
784eef3f2c | ||
|
|
b5f9fbe247 | ||
|
|
da7d2709d9 | ||
|
|
49ba391923 | ||
|
|
7a2d43432e | ||
|
|
643efb3d6b | ||
|
|
99bd6f1872 | ||
|
|
61b67640f4 | ||
|
|
760c7beb94 | ||
|
|
2681b88035 | ||
|
|
8725bf0620 | ||
|
|
f553001217 | ||
|
|
0d81a6409d | ||
|
|
f846c262dc | ||
|
|
30049f622d | ||
|
|
aa54e4bb46 | ||
|
|
a237f691b5 | ||
|
|
1f0ca6b02a | ||
|
|
281cd79b48 | ||
|
|
1cb6d78d35 | ||
|
|
c0f477e5c1 | ||
|
|
66e6c7bb13 | ||
|
|
3ce76e6c08 | ||
|
|
9545598daf | ||
|
|
2ec53bf78c | ||
|
|
0cbb73a47e | ||
|
|
bb845c6d7f | ||
|
|
742cf0a593 | ||
|
|
e4853d0e71 | ||
|
|
787234cf5c | ||
|
|
8f09485414 | ||
|
|
cd632dcfee | ||
|
|
6c3c41e710 | ||
|
|
e2e87980cc | ||
|
|
32c8688805 | ||
|
|
a4209df239 | ||
|
|
6f82b06bd7 | ||
|
|
3e4a6be53f | ||
|
|
430a8e141d | ||
|
|
a07be192fa | ||
|
|
5ad6c05a9c | ||
|
|
3459e5e432 | ||
|
|
47b905bfaf | ||
|
|
6914c4469c | ||
|
|
4825e6b8ba | ||
|
|
65095e0c5f | ||
|
|
0d88d20b56 | ||
|
|
1bc105aff6 | ||
|
|
5418c95a01 | ||
|
|
72942afe3e | ||
|
|
9ced14672d | ||
|
|
d9b3726ee8 | ||
|
|
4070860d2b | ||
|
|
3513bb8eed | ||
|
|
a726aec362 | ||
|
|
944a9e6130 | ||
|
|
b85db2cc35 | ||
|
|
27d1008171 | ||
|
|
da214c89d6 | ||
|
|
ea40e7b29d | ||
|
|
cc898e9b82 | ||
|
|
d9086e6328 | ||
|
|
e020ae77e0 | ||
|
|
dd44187aed | ||
|
|
b107dd6855 | ||
|
|
f8b1aa7e7e | ||
|
|
51d6f752ab | ||
|
|
d5d1365104 | ||
|
|
654c4eea0f | ||
|
|
ef627b4872 | ||
|
|
b414192dcc | ||
|
|
623531a719 | ||
|
|
7fd426e748 | ||
|
|
f589520917 | ||
|
|
4984d8f6f2 | ||
|
|
645364e8b8 | ||
|
|
f5d43b80ed | ||
|
|
f118b39844 | ||
|
|
a5893f38c5 | ||
|
|
d6bdc8c711 | ||
|
|
1f83c5833b | ||
|
|
55e5fa29cb | ||
|
|
57b8830972 | ||
|
|
fc919841ed | ||
|
|
ce1e4ad422 | ||
|
|
00755ecede | ||
|
|
e10042be7d | ||
|
|
38d65d3fae | ||
|
|
75a7bcd3b1 | ||
|
|
f5471e4e1a | ||
|
|
2aec53b7fb | ||
|
|
9102cb5d0d | ||
|
|
8f0b999c31 | ||
|
|
beb0472811 | ||
|
|
25ee5545e6 | ||
|
|
e2caf3e8c0 | ||
|
|
c2679d8632 | ||
|
|
9963def300 | ||
|
|
4a2209752e | ||
|
|
f2e37d25b3 | ||
|
|
e14b803125 | ||
|
|
f737e07e2b | ||
|
|
6ff006ce67 | ||
|
|
f175c60069 | ||
|
|
f47b097d7c | ||
|
|
3f4a330658 | ||
|
|
f14f9375e0 | ||
|
|
20e94b8a38 | ||
|
|
105c0d0dce | ||
|
|
b5aad04f65 | ||
|
|
7b50c958f7 | ||
|
|
52b9ff81c5 | ||
|
|
27bc69883c | ||
|
|
e26a7fc4f3 | ||
|
|
4e453b1ac5 | ||
|
|
0aecbc2a01 | ||
|
|
e8d726606b | ||
|
|
91abf79404 | ||
|
|
2b1423dd74 | ||
|
|
37aa6b2c5f | ||
|
|
dbfd16647b | ||
|
|
290c35e7c6 | ||
|
|
23e0ee66e0 | ||
|
|
beb85c20f2 | ||
|
|
196dfd9385 | ||
|
|
d6ee54eb09 | ||
|
|
8d162fac52 | ||
|
|
bd6acc0d75 | ||
|
|
fc415b32c2 | ||
|
|
e89b42fc11 | ||
|
|
77949cbeb3 | ||
|
|
6e7dcfcc6e | ||
|
|
b1e53280a6 | ||
|
|
bd5fd7d963 | ||
|
|
56292cad26 | ||
|
|
d0814aa37c | ||
|
|
33ba01927f | ||
|
|
f09fc7b0fc | ||
|
|
8b37168223 | ||
|
|
f678c8a967 | ||
|
|
4353937bcf | ||
|
|
ea0ae98e58 | ||
|
|
6aca9b9f49 | ||
|
|
50734c7c6a | ||
|
|
e0ff27331f | ||
|
|
97ffd2d4d9 | ||
|
|
b7367ca649 | ||
|
|
45d64c48e3 | ||
|
|
0634b9b9f7 | ||
|
|
adfd474fee | ||
|
|
b74886a920 | ||
|
|
61b8cee84b | ||
|
|
c21ca8f312 | ||
|
|
5c69b42efa | ||
|
|
99f03a0d61 | ||
|
|
d166727db9 | ||
|
|
4f3c8ec770 | ||
|
|
9887025af2 | ||
|
|
89de63ad1d | ||
|
|
7ea0f8d96b | ||
|
|
c5110e5d68 | ||
|
|
cca5dfbbde | ||
|
|
16973c9a80 | ||
|
|
7806308d5f | ||
|
|
5957494583 | ||
|
|
c9ecb32318 | ||
|
|
56f51ee1ff | ||
|
|
68bf9f39b9 | ||
|
|
dda16a0a30 | ||
|
|
68c2c16928 | ||
|
|
4cd7bf2ebb | ||
|
|
d2a5281d94 | ||
|
|
898689f550 | ||
|
|
7887f669c1 | ||
|
|
131632e7c1 | ||
|
|
b5d18b05e2 | ||
|
|
bb167a3d77 | ||
|
|
c9b14b4459 | ||
|
|
ced36ffc61 | ||
|
|
c7c42acbf5 | ||
|
|
3e5155d1a1 | ||
|
|
ebc7432f46 | ||
|
|
3b4ad3c4f1 | ||
|
|
2e9d9cfb20 | ||
|
|
a5a58d3dc5 | ||
|
|
52d46552af | ||
|
|
c02387a25a | ||
|
|
95bf18fdc9 | ||
|
|
0971ca6a82 | ||
|
|
f4835e3960 | ||
|
|
e71ab59c9a | ||
|
|
be4c2231d1 | ||
|
|
a83ab79d31 | ||
|
|
41274d9e5a | ||
|
|
4bf41d0b81 | ||
|
|
31dddef94e | ||
|
|
83b3125dea | ||
|
|
2c153f68e1 | ||
|
|
d5af30d28d | ||
|
|
1a0abfa7a5 | ||
|
|
4f5c06fed7 | ||
|
|
2d57786dae | ||
|
|
7fd64f1d9c | ||
|
|
926da4bedc | ||
|
|
9a53a40ac6 | ||
|
|
2690732c75 | ||
|
|
698a9e2e2e | ||
|
|
3126fb930d | ||
|
|
456ab980a5 | ||
|
|
0cd2efc1b1 | ||
|
|
dacb7f5f25 | ||
|
|
2aa6dd20ff | ||
|
|
1c5283628b | ||
|
|
53d8bf27ff | ||
|
|
2ad0b2819a | ||
|
|
c225605ed7 | ||
|
|
1d1aa7c8b4 | ||
|
|
4b06bca770 | ||
|
|
ebb1106d9d | ||
|
|
cc7a9ef97a | ||
|
|
7f8fcef62c | ||
|
|
b78faa4b71 | ||
|
|
5fe06abc24 | ||
|
|
5be8e45d09 | ||
|
|
f318dd5e0e | ||
|
|
7d24d96d80 | ||
|
|
02772ed20c | ||
|
|
deecf76fd8 | ||
|
|
2bd866cc82 | ||
|
|
0728ecebbb | ||
|
|
1ca19533e0 | ||
|
|
ef98ce16f8 | ||
|
|
711e769382 | ||
|
|
b951e94d85 | ||
|
|
f20825ae55 | ||
|
|
b21883292d | ||
|
|
a904438828 | ||
|
|
5cd4e0d3b1 | ||
|
|
40b1825ef1 | ||
|
|
9a3b540551 | ||
|
|
fb12d85d3c | ||
|
|
0479a59640 | ||
|
|
5e06277b38 | ||
|
|
d0ecb9f54b | ||
|
|
badb2b7f13 | ||
|
|
ad56274a73 | ||
|
|
df3dc9677f | ||
|
|
a6a30b3725 | ||
|
|
0f63bc077f | ||
|
|
e39229d59e | ||
|
|
d8800c03b6 | ||
|
|
130e1892f4 | ||
|
|
207aebc581 | ||
|
|
36b5e5f61a | ||
|
|
a486a89cee | ||
|
|
acf5b11139 | ||
|
|
15305fd9bb | ||
|
|
7196fdd475 | ||
|
|
af2614be84 | ||
|
|
606b9e6e38 | ||
|
|
5c894ae40b | ||
|
|
6158ee1133 | ||
|
|
170d12bf5a | ||
|
|
f2d9393928 | ||
|
|
80bf22cf6f | ||
|
|
2d90940111 | ||
|
|
ca162a4365 | ||
|
|
69911d4f36 | ||
|
|
92f2976399 | ||
|
|
f248c6a11e | ||
|
|
6b01f02df6 | ||
|
|
a40b7ef81c | ||
|
|
22558e573d | ||
|
|
7070c4a2d2 | ||
|
|
d892304c14 | ||
|
|
3e382fd47c | ||
|
|
38909076ea | ||
|
|
da79ad854c | ||
|
|
2ec3746861 | ||
|
|
f6d42bd3c6 | ||
|
|
11f527ea5b | ||
|
|
354a7fd252 | ||
|
|
5cf320d553 | ||
|
|
b0fbe3658d | ||
|
|
d737b5715f | ||
|
|
e8a1925e9c | ||
|
|
6c08542278 | ||
|
|
1d12bd1521 | ||
|
|
dd51b7f356 | ||
|
|
c1be060ef8 | ||
|
|
4cbfbfe170 | ||
|
|
c62ae3b350 | ||
|
|
76ef779f60 | ||
|
|
94c43c07c7 | ||
|
|
c0da29b204 | ||
|
|
231178d858 | ||
|
|
b69eba9238 | ||
|
|
1ce31ec32c | ||
|
|
6356b20928 | ||
|
|
962069ccff | ||
|
|
48f143e7d4 |
2
.github/workflows/codeql-analysis.yml
vendored
2
.github/workflows/codeql-analysis.yml
vendored
@@ -56,7 +56,7 @@ jobs:
|
||||
# uses a compiled language
|
||||
|
||||
- run: |
|
||||
dotnet build csharp /p:UseSharedCompilation=false
|
||||
dotnet build csharp
|
||||
|
||||
- name: Perform CodeQL Analysis
|
||||
uses: github/codeql-action/analyze@main
|
||||
|
||||
2
.github/workflows/csv-coverage-metrics.yml
vendored
2
.github/workflows/csv-coverage-metrics.yml
vendored
@@ -55,7 +55,7 @@ jobs:
|
||||
DATABASE="${{ runner.temp }}/csharp-database"
|
||||
PROJECT="${{ runner.temp }}/csharp-project"
|
||||
dotnet new classlib --language=C# --output="$PROJECT"
|
||||
codeql database create "$DATABASE" --language=csharp --source-root="$PROJECT" --command 'dotnet build /t:rebuild csharp-project.csproj /p:UseSharedCompilation=false'
|
||||
codeql database create "$DATABASE" --language=csharp --source-root="$PROJECT" --command 'dotnet build /t:rebuild csharp-project.csproj'
|
||||
- name: Capture coverage information
|
||||
run: |
|
||||
DATABASE="${{ runner.temp }}/csharp-database"
|
||||
|
||||
21
.github/workflows/ql-for-ql-build.yml
vendored
21
.github/workflows/ql-for-ql-build.yml
vendored
@@ -5,6 +5,13 @@ on:
|
||||
branches: [main]
|
||||
pull_request:
|
||||
branches: [main]
|
||||
paths:
|
||||
- "ql/**"
|
||||
- "**.qll"
|
||||
- "**.ql"
|
||||
- "**.dbscheme"
|
||||
- "**/qlpack.yml"
|
||||
- ".github/workflows/ql-for-ql-build.yml"
|
||||
|
||||
env:
|
||||
CARGO_TERM_COLOR: always
|
||||
@@ -54,7 +61,7 @@ jobs:
|
||||
cp -r ${{ runner.temp }}/queries ${{ runner.temp }}/pack
|
||||
env:
|
||||
CODEQL: ${{ steps.find-codeql.outputs.codeql-path }}
|
||||
|
||||
|
||||
### Build the extractor ###
|
||||
- name: Cache entire extractor
|
||||
if: steps.cache-pack.outputs.cache-hit != 'true'
|
||||
@@ -108,7 +115,7 @@ jobs:
|
||||
### Run the analysis ###
|
||||
- name: Hack codeql-action options
|
||||
run: |
|
||||
JSON=$(jq -nc --arg pack "${PACK}" '.database."run-queries"=["--search-path", $pack] | .resolve.queries=["--search-path", $pack] | .resolve.extractor=["--search-path", $pack] | .database.init=["--search-path", $pack]')
|
||||
JSON=$(jq -nc --arg pack "${PACK}" '.database."run-queries"=["--search-path", $pack] | .resolve.queries=["--search-path", $pack] | .resolve.extractor=["--search-path", $pack] | .resolve.languages=["--search-path", $pack] | .database.init=["--search-path", $pack]')
|
||||
echo "CODEQL_ACTION_EXTRA_OPTIONS=${JSON}" >> ${GITHUB_ENV}
|
||||
env:
|
||||
PACK: ${{ runner.temp }}/pack
|
||||
@@ -116,14 +123,14 @@ jobs:
|
||||
- name: Create CodeQL config file
|
||||
run: |
|
||||
echo "paths-ignore:" >> ${CONF}
|
||||
echo " - ql/ql/test" >> ${CONF}
|
||||
echo " - \"*/ql/lib/upgrades/\"" >> ${CONF}
|
||||
echo " - ql/ql/test" >> ${CONF}
|
||||
echo " - \"*/ql/lib/upgrades/\"" >> ${CONF}
|
||||
echo "disable-default-queries: true" >> ${CONF}
|
||||
echo "queries:" >> ${CONF}
|
||||
echo " - uses: ./ql/ql/src/codeql-suites/ql-code-scanning.qls" >> ${CONF}
|
||||
echo "Config file: "
|
||||
cat ${CONF}
|
||||
env:
|
||||
env:
|
||||
CONF: ./ql-for-ql-config.yml
|
||||
- name: Initialize CodeQL
|
||||
uses: github/codeql-action/init@71a8b35ff4c80fcfcd05bc1cd932fe3c08f943ca
|
||||
@@ -139,13 +146,13 @@ jobs:
|
||||
|
||||
- name: Perform CodeQL Analysis
|
||||
uses: github/codeql-action/analyze@71a8b35ff4c80fcfcd05bc1cd932fe3c08f943ca
|
||||
with:
|
||||
with:
|
||||
category: "ql-for-ql"
|
||||
- name: Copy sarif file to CWD
|
||||
run: cp ../results/ql.sarif ./ql-for-ql.sarif
|
||||
- name: Fixup the $scema in sarif # Until https://github.com/microsoft/sarif-vscode-extension/pull/436/ is part in a stable release
|
||||
run: |
|
||||
sed -i 's/\$schema.*/\$schema": "https:\/\/raw.githubusercontent.com\/oasis-tcs\/sarif-spec\/master\/Schemata\/sarif-schema-2.1.0",/' ql-for-ql.sarif
|
||||
sed -i 's/\$schema.*/\$schema": "https:\/\/raw.githubusercontent.com\/oasis-tcs\/sarif-spec\/master\/Schemata\/sarif-schema-2.1.0",/' ql-for-ql.sarif
|
||||
- name: Sarif as artifact
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
|
||||
@@ -462,9 +462,6 @@
|
||||
],
|
||||
"SSA C#": [
|
||||
"csharp/ql/lib/semmle/code/csharp/dataflow/internal/SsaImplCommon.qll",
|
||||
"csharp/ql/lib/semmle/code/csharp/controlflow/internal/pressa/SsaImplCommon.qll",
|
||||
"csharp/ql/lib/semmle/code/csharp/dataflow/internal/basessa/SsaImplCommon.qll",
|
||||
"csharp/ql/lib/semmle/code/cil/internal/SsaImplCommon.qll",
|
||||
"ruby/ql/lib/codeql/ruby/dataflow/internal/SsaImplCommon.qll",
|
||||
"cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/SsaImplCommon.qll",
|
||||
"swift/ql/lib/codeql/swift/dataflow/internal/SsaImplCommon.qll"
|
||||
@@ -584,22 +581,22 @@
|
||||
],
|
||||
"Swift declarations test file": [
|
||||
"swift/ql/test/extractor-tests/declarations/declarations.swift",
|
||||
"swift/ql/test/library-tests/parent/declarations.swift"
|
||||
"swift/ql/test/library-tests/ast/declarations.swift"
|
||||
],
|
||||
"Swift statements test file": [
|
||||
"swift/ql/test/extractor-tests/statements/statements.swift",
|
||||
"swift/ql/test/library-tests/parent/statements.swift"
|
||||
"swift/ql/test/library-tests/ast/statements.swift"
|
||||
],
|
||||
"Swift expressions test file": [
|
||||
"swift/ql/test/extractor-tests/expressions/expressions.swift",
|
||||
"swift/ql/test/library-tests/parent/expressions.swift"
|
||||
"swift/ql/test/library-tests/ast/expressions.swift"
|
||||
],
|
||||
"Swift patterns test file": [
|
||||
"swift/ql/test/extractor-tests/patterns/patterns.swift",
|
||||
"swift/ql/test/library-tests/parent/patterns.swift"
|
||||
"swift/ql/test/library-tests/ast/patterns.swift"
|
||||
],
|
||||
"IncompleteMultiCharacterSanitization JS/Ruby": [
|
||||
"javascript/ql/lib/semmle/javascript/security/IncompleteMultiCharacterSanitizationQuery.qll",
|
||||
"ruby/ql/lib/codeql/ruby/security/IncompleteMultiCharacterSanitizationQuery.qll"
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -299,7 +299,7 @@ namespace Semmle.Autobuild.Cpp.Tests
|
||||
{
|
||||
Actions.RunProcess[@"cmd.exe /C nuget restore C:\Project\test.sln -DisableParallelProcessing"] = 1;
|
||||
Actions.RunProcess[@"cmd.exe /C C:\Project\.nuget\nuget.exe restore C:\Project\test.sln -DisableParallelProcessing"] = 0;
|
||||
Actions.RunProcess[@"cmd.exe /C CALL ^""C:\Program Files ^(x86^)\Microsoft Visual Studio 14.0\VC\vcvarsall.bat^"" && set Platform=&& type NUL && C:\odasa\tools\odasa index --auto msbuild C:\Project\test.sln /p:UseSharedCompilation=false /t:rebuild /p:Platform=""x86"" /p:Configuration=""Release"" /p:MvcBuildViews=true"] = 0;
|
||||
Actions.RunProcess[@"cmd.exe /C CALL ^""C:\Program Files ^(x86^)\Microsoft Visual Studio 14.0\VC\vcvarsall.bat^"" && set Platform=&& type NUL && C:\odasa\tools\odasa index --auto msbuild C:\Project\test.sln /t:rebuild /p:Platform=""x86"" /p:Configuration=""Release"" /p:MvcBuildViews=true"] = 0;
|
||||
Actions.RunProcessOut[@"C:\Program Files (x86)\Microsoft Visual Studio\Installer\vswhere.exe -prerelease -legacy -property installationPath"] = "";
|
||||
Actions.RunProcess[@"C:\Program Files (x86)\Microsoft Visual Studio\Installer\vswhere.exe -prerelease -legacy -property installationPath"] = 1;
|
||||
Actions.RunProcess[@"C:\Program Files (x86)\Microsoft Visual Studio\Installer\vswhere.exe -prerelease -legacy -property installationVersion"] = 0;
|
||||
|
||||
@@ -1,3 +1,19 @@
|
||||
## 0.3.4
|
||||
|
||||
### Deprecated APIs
|
||||
|
||||
* Many classes/predicates/modules with upper-case acronyms in their name have been renamed to follow our style-guide.
|
||||
The old name still exists as a deprecated alias.
|
||||
|
||||
### New Features
|
||||
|
||||
* Added support for getting the link targets of global and namespace variables.
|
||||
* Added a `BlockAssignExpr` class, which models a `memcpy`-like operation used in compiler generated copy/move constructors and assignment operations.
|
||||
|
||||
### Minor Analysis Improvements
|
||||
|
||||
* All deprecated predicates/classes/modules that have been deprecated for over a year have been deleted.
|
||||
|
||||
## 0.3.3
|
||||
|
||||
### New Features
|
||||
|
||||
@@ -1,4 +0,0 @@
|
||||
---
|
||||
category: minorAnalysis
|
||||
---
|
||||
* Multiple function calls made in the same function may now receive the same global value number when the analysis can show they produce the same results.
|
||||
@@ -1,4 +0,0 @@
|
||||
---
|
||||
category: feature
|
||||
---
|
||||
* Added a `BlockAssignExpr` class, which models a `memcpy`-like operation used in compiler generated copy/move constructors and assignment operations.
|
||||
@@ -1,6 +0,0 @@
|
||||
---
|
||||
category: minorAnalysis
|
||||
---
|
||||
* All deprecated predicates/classes/modules that have been deprecated for over a year have been
|
||||
deleted.
|
||||
|
||||
@@ -1,4 +0,0 @@
|
||||
---
|
||||
category: feature
|
||||
---
|
||||
* Added support for getting the link targets of global and namespace variables.
|
||||
@@ -1,5 +0,0 @@
|
||||
---
|
||||
category: deprecated
|
||||
---
|
||||
* Many classes/predicates/modules with upper-case acronyms in their name have been renamed to follow our style-guide.
|
||||
The old name still exists as a deprecated alias.
|
||||
15
cpp/ql/lib/change-notes/released/0.3.4.md
Normal file
15
cpp/ql/lib/change-notes/released/0.3.4.md
Normal file
@@ -0,0 +1,15 @@
|
||||
## 0.3.4
|
||||
|
||||
### Deprecated APIs
|
||||
|
||||
* Many classes/predicates/modules with upper-case acronyms in their name have been renamed to follow our style-guide.
|
||||
The old name still exists as a deprecated alias.
|
||||
|
||||
### New Features
|
||||
|
||||
* Added support for getting the link targets of global and namespace variables.
|
||||
* Added a `BlockAssignExpr` class, which models a `memcpy`-like operation used in compiler generated copy/move constructors and assignment operations.
|
||||
|
||||
### Minor Analysis Improvements
|
||||
|
||||
* All deprecated predicates/classes/modules that have been deprecated for over a year have been deleted.
|
||||
@@ -1,2 +1,2 @@
|
||||
---
|
||||
lastReleaseVersion: 0.3.3
|
||||
lastReleaseVersion: 0.3.4
|
||||
|
||||
@@ -162,7 +162,7 @@ module SemanticExprConfig {
|
||||
predicate phi(SsaVariable v) { v.asInstruction() instanceof IR::PhiInstruction }
|
||||
|
||||
SsaVariable getAPhiInput(SsaVariable v) {
|
||||
exists(IR::PhiInstruction instr |
|
||||
exists(IR::PhiInstruction instr | v.asInstruction() = instr |
|
||||
result.asInstruction() = instr.getAnInput()
|
||||
or
|
||||
result.asOperand() = instr.getAnInputOperand()
|
||||
|
||||
@@ -204,6 +204,7 @@ private class BinarySignExpr extends FlowSignExpr {
|
||||
}
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate binaryExprOperands(SemBinaryExpr binary, SemExpr left, SemExpr right) {
|
||||
binary.getLeftOperand() = left and binary.getRightOperand() = right
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
name: codeql/cpp-all
|
||||
version: 0.3.4-dev
|
||||
version: 0.3.5-dev
|
||||
groups: cpp
|
||||
dbscheme: semmlecode.cpp.dbscheme
|
||||
extractor: cpp
|
||||
|
||||
@@ -404,7 +404,10 @@ class Class extends UserType {
|
||||
* compiled for. For this reason, the `is_pod_class` predicate is
|
||||
* generated by the extractor.
|
||||
*/
|
||||
predicate isPOD() { is_pod_class(underlyingElement(this)) }
|
||||
predicate isPod() { is_pod_class(underlyingElement(this)) }
|
||||
|
||||
/** DEPRECATED: Alias for isPod */
|
||||
deprecated predicate isPOD() { this.isPod() }
|
||||
|
||||
/**
|
||||
* Holds if this class, struct or union is a standard-layout class
|
||||
|
||||
@@ -79,17 +79,17 @@ predicate isAggregateType03(Type t) {
|
||||
* user-defined copy assignment operator and no user-defined destructor.
|
||||
* A POD class is a class that is either a POD-struct or a POD-union.
|
||||
*/
|
||||
predicate isPODClass03(Class c) {
|
||||
predicate isPodClass03(Class c) {
|
||||
isAggregateClass03(c) and
|
||||
not exists(Variable v |
|
||||
v.getDeclaringType() = c and
|
||||
not v.isStatic()
|
||||
|
|
||||
not isPODType03(v.getType())
|
||||
not isPodType03(v.getType())
|
||||
or
|
||||
exists(ArrayType at |
|
||||
at = v.getType() and
|
||||
not isPODType03(at.getBaseType())
|
||||
not isPodType03(at.getBaseType())
|
||||
)
|
||||
or
|
||||
v.getType() instanceof ReferenceType
|
||||
@@ -104,6 +104,9 @@ predicate isPODClass03(Class c) {
|
||||
)
|
||||
}
|
||||
|
||||
/** DEPRECATED: Alias for isPodClass03 */
|
||||
deprecated predicate isPODClass03 = isPodClass03/1;
|
||||
|
||||
/**
|
||||
* Holds if `t` is a POD type, according to the rules specified in
|
||||
* C++03 3.9(10):
|
||||
@@ -112,14 +115,17 @@ predicate isPODClass03(Class c) {
|
||||
* such types and cv-qualified versions of these types (3.9.3) are
|
||||
* collectively called POD types.
|
||||
*/
|
||||
predicate isPODType03(Type t) {
|
||||
predicate isPodType03(Type t) {
|
||||
exists(Type ut | ut = t.getUnderlyingType() |
|
||||
isScalarType03(ut)
|
||||
or
|
||||
isPODClass03(ut)
|
||||
isPodClass03(ut)
|
||||
or
|
||||
exists(ArrayType at | at = ut and isPODType03(at.getBaseType()))
|
||||
exists(ArrayType at | at = ut and isPodType03(at.getBaseType()))
|
||||
or
|
||||
isPODType03(ut.(SpecifiedType).getUnspecifiedType())
|
||||
isPodType03(ut.(SpecifiedType).getUnspecifiedType())
|
||||
)
|
||||
}
|
||||
|
||||
/** DEPRECATED: Alias for isPodType03 */
|
||||
deprecated predicate isPODType03 = isPodType03/1;
|
||||
|
||||
@@ -238,7 +238,7 @@ predicate dependsOnTransitive(DependsSource src, Element dest) {
|
||||
/**
|
||||
* A dependency that targets a TypeDeclarationEntry.
|
||||
*/
|
||||
private predicate dependsOnTDE(Element src, Type t, TypeDeclarationEntry dest) {
|
||||
private predicate dependsOnTde(Element src, Type t, TypeDeclarationEntry dest) {
|
||||
dependsOnTransitive(src, t) and
|
||||
getDeclarationEntries(t, dest)
|
||||
}
|
||||
@@ -247,8 +247,8 @@ private predicate dependsOnTDE(Element src, Type t, TypeDeclarationEntry dest) {
|
||||
* A dependency that targets a visible TypeDeclarationEntry.
|
||||
*/
|
||||
pragma[noopt]
|
||||
private predicate dependsOnVisibleTDE(Element src, Type t, TypeDeclarationEntry dest) {
|
||||
dependsOnTDE(src, t, dest) and
|
||||
private predicate dependsOnVisibleTde(Element src, Type t, TypeDeclarationEntry dest) {
|
||||
dependsOnTde(src, t, dest) and
|
||||
exists(File g | g = dest.getFile() |
|
||||
exists(File f | f = src.getFile() | f.getAnIncludedFile*() = g)
|
||||
)
|
||||
@@ -260,8 +260,8 @@ private predicate dependsOnVisibleTDE(Element src, Type t, TypeDeclarationEntry
|
||||
private predicate dependsOnDeclarationEntry(Element src, DeclarationEntry dest) {
|
||||
exists(Type t |
|
||||
// dependency from a Type use -> unique visible TDE
|
||||
dependsOnVisibleTDE(src, t, dest) and
|
||||
strictcount(TypeDeclarationEntry alt | dependsOnVisibleTDE(src, t, alt)) = 1
|
||||
dependsOnVisibleTde(src, t, dest) and
|
||||
strictcount(TypeDeclarationEntry alt | dependsOnVisibleTde(src, t, alt)) = 1
|
||||
)
|
||||
or
|
||||
exists(TypedefType mid |
|
||||
|
||||
@@ -1,11 +1,14 @@
|
||||
import semmle.code.cpp.Macro
|
||||
|
||||
/** A macro defining NULL. */
|
||||
class NULLMacro extends Macro {
|
||||
NULLMacro() { this.getHead() = "NULL" }
|
||||
class NullMacro extends Macro {
|
||||
NullMacro() { this.getHead() = "NULL" }
|
||||
}
|
||||
|
||||
/** DEPRECATED: Alias for NullMacro */
|
||||
deprecated class NULLMacro = NullMacro;
|
||||
|
||||
/** A use of the NULL macro. */
|
||||
class NULL extends Literal {
|
||||
NULL() { exists(NULLMacro nm | this = nm.getAnInvocation().getAnExpandedElement()) }
|
||||
NULL() { exists(NullMacro nm | this = nm.getAnInvocation().getAnExpandedElement()) }
|
||||
}
|
||||
|
||||
@@ -143,6 +143,28 @@ class ScanfFunctionCall extends FunctionCall {
|
||||
* (rather than a `char*`).
|
||||
*/
|
||||
predicate isWideCharDefault() { this.getScanfFunction().isWideCharDefault() }
|
||||
|
||||
/**
|
||||
* Gets the output argument at position `n` in the vararg list of this call.
|
||||
*
|
||||
* The range of `n` is from `0` to `this.getNumberOfOutputArguments() - 1`.
|
||||
*/
|
||||
Expr getOutputArgument(int n) {
|
||||
result = this.getArgument(this.getTarget().getNumberOfParameters() + n) and
|
||||
n >= 0
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets an output argument given to this call in vararg position.
|
||||
*/
|
||||
Expr getAnOutputArgument() { result = this.getOutputArgument(_) }
|
||||
|
||||
/**
|
||||
* Gets the number of output arguments present in this call.
|
||||
*/
|
||||
int getNumberOfOutputArguments() {
|
||||
result = this.getNumberOfArguments() - this.getTarget().getNumberOfParameters()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -474,7 +474,7 @@ module FlowVar_internal {
|
||||
}
|
||||
|
||||
/** Type-specialized version of `getEnclosingElement`. */
|
||||
private ControlFlowNode getCFNParent(ControlFlowNode node) { result = node.getEnclosingElement() }
|
||||
private ControlFlowNode getCfnParent(ControlFlowNode node) { result = node.getEnclosingElement() }
|
||||
|
||||
/**
|
||||
* A for-loop or while-loop whose condition is always true upon entry but not
|
||||
@@ -526,7 +526,7 @@ module FlowVar_internal {
|
||||
}
|
||||
|
||||
private predicate bbInLoopCondition(BasicBlock bb) {
|
||||
getCFNParent*(bb.getANode()) = this.(Loop).getCondition()
|
||||
getCfnParent*(bb.getANode()) = this.(Loop).getCondition()
|
||||
}
|
||||
|
||||
private predicate bbInLoop(BasicBlock bb) {
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,18 +0,0 @@
|
||||
private import semmle.code.cpp.ir.IR
|
||||
private import SsaInternals as Ssa
|
||||
|
||||
class BasicBlock = IRBlock;
|
||||
|
||||
class SourceVariable = Ssa::SourceVariable;
|
||||
|
||||
BasicBlock getImmediateBasicBlockDominator(BasicBlock bb) { result.immediatelyDominates(bb) }
|
||||
|
||||
BasicBlock getABasicBlockSuccessor(BasicBlock bb) { result = bb.getASuccessor() }
|
||||
|
||||
class ExitBasicBlock extends IRBlock {
|
||||
ExitBasicBlock() { this.getLastInstruction() instanceof ExitFunctionInstruction }
|
||||
}
|
||||
|
||||
predicate variableWrite = Ssa::variableWrite/4;
|
||||
|
||||
predicate variableRead = Ssa::variableRead/4;
|
||||
@@ -1,10 +1,10 @@
|
||||
import SsaImplCommon
|
||||
private import cpp as Cpp
|
||||
private import semmle.code.cpp.ir.IR
|
||||
private import DataFlowUtil
|
||||
private import DataFlowImplCommon as DataFlowImplCommon
|
||||
private import semmle.code.cpp.models.interfaces.Allocation as Alloc
|
||||
private import semmle.code.cpp.models.interfaces.DataFlow as DataFlow
|
||||
private import SsaImplCommon as SsaImplCommon
|
||||
|
||||
private module SourceVariables {
|
||||
private newtype TSourceVariable =
|
||||
@@ -38,8 +38,6 @@ private module SourceVariables {
|
||||
}
|
||||
}
|
||||
|
||||
import SourceVariables
|
||||
|
||||
cached
|
||||
private newtype TDefOrUse =
|
||||
TExplicitDef(Instruction store) { explicitWrite(_, store, _) } or
|
||||
@@ -86,7 +84,7 @@ abstract class Def extends DefOrUse {
|
||||
Instruction getInstruction() { result = store }
|
||||
|
||||
/** Gets the variable that is defined by this definition. */
|
||||
abstract SourceVariable getSourceVariable();
|
||||
abstract SourceVariables::SourceVariable getSourceVariable();
|
||||
|
||||
/** Holds if this definition is guaranteed to happen. */
|
||||
abstract predicate isCertain();
|
||||
@@ -103,10 +101,10 @@ abstract class Def extends DefOrUse {
|
||||
private class ExplicitDef extends Def, TExplicitDef {
|
||||
ExplicitDef() { this = TExplicitDef(store) }
|
||||
|
||||
override SourceVariable getSourceVariable() {
|
||||
override SourceVariables::SourceVariable getSourceVariable() {
|
||||
exists(VariableInstruction var |
|
||||
explicitWrite(_, this.getInstruction(), var) and
|
||||
result.(SourceIRVariable).getIRVariable() = var.getIRVariable()
|
||||
result.(SourceVariables::SourceIRVariable).getIRVariable() = var.getIRVariable()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -116,11 +114,11 @@ private class ExplicitDef extends Def, TExplicitDef {
|
||||
private class ParameterDef extends Def, TInitializeParam {
|
||||
ParameterDef() { this = TInitializeParam(store) }
|
||||
|
||||
override SourceVariable getSourceVariable() {
|
||||
result.(SourceIRVariable).getIRVariable() =
|
||||
override SourceVariables::SourceVariable getSourceVariable() {
|
||||
result.(SourceVariables::SourceIRVariable).getIRVariable() =
|
||||
store.(InitializeParameterInstruction).getIRVariable()
|
||||
or
|
||||
result.(SourceIRVariableIndirection).getUnderlyingIRVariable() =
|
||||
result.(SourceVariables::SourceIRVariableIndirection).getUnderlyingIRVariable() =
|
||||
store.(InitializeIndirectionInstruction).getIRVariable()
|
||||
}
|
||||
|
||||
@@ -138,7 +136,7 @@ abstract class Use extends DefOrUse {
|
||||
override string toString() { result = "Use" }
|
||||
|
||||
/** Gets the variable that is used by this use. */
|
||||
abstract SourceVariable getSourceVariable();
|
||||
abstract SourceVariables::SourceVariable getSourceVariable();
|
||||
|
||||
override IRBlock getBlock() { result = use.getUse().getBlock() }
|
||||
|
||||
@@ -148,12 +146,14 @@ abstract class Use extends DefOrUse {
|
||||
private class ExplicitUse extends Use, TExplicitUse {
|
||||
ExplicitUse() { this = TExplicitUse(use) }
|
||||
|
||||
override SourceVariable getSourceVariable() {
|
||||
override SourceVariables::SourceVariable getSourceVariable() {
|
||||
exists(VariableInstruction var |
|
||||
use.getDef() = var and
|
||||
if use.getUse() instanceof ReadSideEffectInstruction
|
||||
then result.(SourceIRVariableIndirection).getUnderlyingIRVariable() = var.getIRVariable()
|
||||
else result.(SourceIRVariable).getIRVariable() = var.getIRVariable()
|
||||
then
|
||||
result.(SourceVariables::SourceIRVariableIndirection).getUnderlyingIRVariable() =
|
||||
var.getIRVariable()
|
||||
else result.(SourceVariables::SourceIRVariable).getIRVariable() = var.getIRVariable()
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -161,10 +161,11 @@ private class ExplicitUse extends Use, TExplicitUse {
|
||||
private class ReturnParameterIndirection extends Use, TReturnParamIndirection {
|
||||
ReturnParameterIndirection() { this = TReturnParamIndirection(use) }
|
||||
|
||||
override SourceVariable getSourceVariable() {
|
||||
override SourceVariables::SourceVariable getSourceVariable() {
|
||||
exists(ReturnIndirectionInstruction ret |
|
||||
returnParameterIndirection(use, ret) and
|
||||
result.(SourceIRVariableIndirection).getUnderlyingIRVariable() = ret.getIRVariable()
|
||||
result.(SourceVariables::SourceIRVariableIndirection).getUnderlyingIRVariable() =
|
||||
ret.getIRVariable()
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -610,27 +611,45 @@ private module Cached {
|
||||
|
||||
import Cached
|
||||
|
||||
/**
|
||||
* Holds if the `i`'th write in block `bb` writes to the variable `v`.
|
||||
* `certain` is `true` if the write is guaranteed to overwrite the entire variable.
|
||||
*/
|
||||
predicate variableWrite(IRBlock bb, int i, SourceVariable v, boolean certain) {
|
||||
DataFlowImplCommon::forceCachingInSameStage() and
|
||||
exists(Def def |
|
||||
def.hasIndexInBlock(bb, i) and
|
||||
v = def.getSourceVariable() and
|
||||
(if def.isCertain() then certain = true else certain = false)
|
||||
)
|
||||
private module SsaInput implements SsaImplCommon::InputSig {
|
||||
private import semmle.code.cpp.ir.IR
|
||||
|
||||
class BasicBlock = IRBlock;
|
||||
|
||||
class SourceVariable = SourceVariables::SourceVariable;
|
||||
|
||||
BasicBlock getImmediateBasicBlockDominator(BasicBlock bb) { result.immediatelyDominates(bb) }
|
||||
|
||||
BasicBlock getABasicBlockSuccessor(BasicBlock bb) { result = bb.getASuccessor() }
|
||||
|
||||
class ExitBasicBlock extends IRBlock {
|
||||
ExitBasicBlock() { this.getLastInstruction() instanceof ExitFunctionInstruction }
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if the `i`'th write in block `bb` writes to the variable `v`.
|
||||
* `certain` is `true` if the write is guaranteed to overwrite the entire variable.
|
||||
*/
|
||||
predicate variableWrite(BasicBlock bb, int i, SourceVariable v, boolean certain) {
|
||||
DataFlowImplCommon::forceCachingInSameStage() and
|
||||
exists(Def def |
|
||||
def.hasIndexInBlock(bb, i) and
|
||||
v = def.getSourceVariable() and
|
||||
(if def.isCertain() then certain = true else certain = false)
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if the `i`'th read in block `bb` reads to the variable `v`.
|
||||
* `certain` is `true` if the read is guaranteed. For C++, this is always the case.
|
||||
*/
|
||||
predicate variableRead(BasicBlock bb, int i, SourceVariable v, boolean certain) {
|
||||
exists(Use use |
|
||||
use.hasIndexInBlock(bb, i) and
|
||||
v = use.getSourceVariable() and
|
||||
certain = true
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if the `i`'th read in block `bb` reads to the variable `v`.
|
||||
* `certain` is `true` if the read is guaranteed. For C++, this is always the case.
|
||||
*/
|
||||
predicate variableRead(IRBlock bb, int i, SourceVariable v, boolean certain) {
|
||||
exists(Use use |
|
||||
use.hasIndexInBlock(bb, i) and
|
||||
v = use.getSourceVariable() and
|
||||
certain = true
|
||||
)
|
||||
}
|
||||
import SsaImplCommon::Make<SsaInput>
|
||||
|
||||
@@ -1712,11 +1712,6 @@ class SideEffectInstruction extends Instruction {
|
||||
*/
|
||||
class CallSideEffectInstruction extends SideEffectInstruction {
|
||||
CallSideEffectInstruction() { this.getOpcode() instanceof Opcode::CallSideEffect }
|
||||
|
||||
/** Gets the operand for the value that will be read by this instruction */
|
||||
final SideEffectOperand getSideEffectOperand() { result = this.getAnOperand() }
|
||||
|
||||
final Instruction getSideEffect() { result = this.getAnOperand().getDef() }
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1728,11 +1723,6 @@ class CallSideEffectInstruction extends SideEffectInstruction {
|
||||
*/
|
||||
class CallReadSideEffectInstruction extends SideEffectInstruction {
|
||||
CallReadSideEffectInstruction() { this.getOpcode() instanceof Opcode::CallReadSideEffect }
|
||||
|
||||
/** Gets the operand for the value that will be read by this instruction */
|
||||
final SideEffectOperand getSideEffectOperand() { result = this.getAnOperand() }
|
||||
|
||||
final Instruction getSideEffect() { result = this.getAnOperand().getDef() }
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import semmle.code.cpp.ir.implementation.aliased_ssa.IR
|
||||
import semmle.code.cpp.ir.internal.Overlap
|
||||
import semmle.code.cpp.ir.internal.IRCppLanguage as Language
|
||||
import semmle.code.cpp.models.interfaces.SideEffect as SideEffect
|
||||
|
||||
@@ -41,92 +41,8 @@ newtype TValueNumber =
|
||||
) {
|
||||
loadTotalOverlapValueNumber(_, irFunc, type, memOperand, operand)
|
||||
} or
|
||||
TCallValueNumber(TCallPartialValueNumber vn) { callValueNumber(_, _, vn) } or
|
||||
TUniqueValueNumber(IRFunction irFunc, Instruction instr) { uniqueValueNumber(instr, irFunc) }
|
||||
|
||||
private class NumberableCallInstruction extends CallInstruction {
|
||||
NumberableCallInstruction() {
|
||||
not this.getResultIRType() instanceof IRVoidType and
|
||||
exists(SideEffect::SideEffectFunction sideEffectFunc |
|
||||
sideEffectFunc = this.getStaticCallTarget()
|
||||
|
|
||||
sideEffectFunc.hasOnlySpecificReadSideEffects() and
|
||||
sideEffectFunc.hasOnlySpecificWriteSideEffects()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private newtype TCallPartialValueNumber =
|
||||
TNilArgument() or
|
||||
TArgument(TCallPartialValueNumber head, TValueNumber arg) {
|
||||
exists(NumberableCallInstruction call, int index |
|
||||
callArgValueNumber(call, index, arg) and
|
||||
callPartialValueNumber(call, index, head)
|
||||
)
|
||||
}
|
||||
|
||||
private predicate callValueNumber(
|
||||
NumberableCallInstruction call, int index, TCallPartialValueNumber vn
|
||||
) {
|
||||
index = max(int n | callArgRank(call, n, _) | n) and
|
||||
exists(TCallPartialValueNumber head, TValueNumber arg |
|
||||
callPartialValueNumber(call, index, pragma[only_bind_out](head)) and
|
||||
callArgValueNumber(call, index, pragma[only_bind_into](arg)) and
|
||||
vn = TArgument(head, arg)
|
||||
)
|
||||
or
|
||||
not exists(int n | callArgRank(call, n, _)) and
|
||||
index = -1 and
|
||||
vn = TNilArgument()
|
||||
}
|
||||
|
||||
private predicate callPartialValueNumber(
|
||||
NumberableCallInstruction call, int index, TCallPartialValueNumber head
|
||||
) {
|
||||
exists(call) and
|
||||
index = 1 and
|
||||
head = TNilArgument()
|
||||
or
|
||||
exists(TCallPartialValueNumber prev, TValueNumber prevVN |
|
||||
callPartialValueNumber(call, index - 1, pragma[only_bind_out](prev)) and
|
||||
callArgValueNumber(call, index - 1, pragma[only_bind_into](prevVN)) and
|
||||
head = TArgument(prev, prevVN)
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
*/
|
||||
private predicate callArgValueNumber(NumberableCallInstruction call, int index, TValueNumber arg) {
|
||||
exists(Instruction instr |
|
||||
callArgRank(call, index, instr) and
|
||||
arg = tvalueNumber(instr)
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if `arg` is the `index`th element in `call`'s extended argument list, including the `this`
|
||||
* argument and side-effect reads.
|
||||
*/
|
||||
private predicate callArgRank(NumberableCallInstruction call, int index, Instruction arg) {
|
||||
arg =
|
||||
rank[index](int argIndex, boolean isEffect, Instruction instr |
|
||||
// There is no need to include the call's read and write side effects on
|
||||
// all-aliased-memory as `NumberableCallInstruction`s do not read or write
|
||||
// to all-aliased-memory.
|
||||
instr = call.getArgument(argIndex) and
|
||||
isEffect = false
|
||||
or
|
||||
exists(ReadSideEffectInstruction read |
|
||||
read.getPrimaryInstruction() = call and
|
||||
read.getSideEffectOperand().getAnyDef() = instr and
|
||||
read.getIndex() = argIndex and
|
||||
isEffect = true
|
||||
)
|
||||
|
|
||||
instr order by argIndex, isEffect
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* A `CopyInstruction` whose source operand's value is congruent to the definition of that source
|
||||
* operand.
|
||||
@@ -177,8 +93,6 @@ private predicate numberableInstruction(Instruction instr) {
|
||||
instr instanceof CongruentCopyInstruction
|
||||
or
|
||||
instr instanceof LoadTotalOverlapInstruction
|
||||
or
|
||||
instr instanceof NumberableCallInstruction
|
||||
}
|
||||
|
||||
private predicate filteredNumberableInstruction(Instruction instr) {
|
||||
@@ -395,11 +309,6 @@ private TValueNumber nonUniqueValueNumber(Instruction instr) {
|
||||
or
|
||||
// The value number of a copy is just the value number of its source value.
|
||||
result = tvalueNumber(instr.(CongruentCopyInstruction).getSourceValue())
|
||||
or
|
||||
exists(TCallPartialValueNumber pvn |
|
||||
callValueNumber(instr, _, pvn) and
|
||||
result = TCallValueNumber(pvn)
|
||||
)
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -8,6 +8,11 @@ private import Imports::RawIR as RawIR
|
||||
private import SsaInstructions
|
||||
private import SsaOperands
|
||||
private import NewIR
|
||||
|
||||
private class OldBlock = Reachability::ReachableBlock;
|
||||
|
||||
private class OldInstruction = Reachability::ReachableInstruction;
|
||||
|
||||
import Cached
|
||||
|
||||
cached
|
||||
@@ -53,9 +58,7 @@ private module Cached {
|
||||
|
||||
cached
|
||||
predicate hasInstruction(TStageInstruction instr) {
|
||||
instr instanceof TRawInstruction and
|
||||
instr instanceof OldInstruction and
|
||||
not removedInstruction(instr)
|
||||
instr instanceof TRawInstruction and instr instanceof OldInstruction
|
||||
or
|
||||
instr = phiInstruction(_, _)
|
||||
or
|
||||
@@ -379,14 +382,7 @@ private module Cached {
|
||||
(
|
||||
if Reachability::isInfeasibleInstructionSuccessor(oldInstruction, kind)
|
||||
then result = unreachedInstruction(instruction.getEnclosingIRFunction())
|
||||
else
|
||||
if removedInstruction(oldInstruction.getSuccessor(kind))
|
||||
then
|
||||
// the only removed nodes are side-effect writes, but those may have Chi nodes
|
||||
// skip to the following instruction in the old IR, which won't be removed
|
||||
// if we start skipping specific side effects, this may no longer hold
|
||||
result = getNewInstruction(oldInstruction.getSuccessor(kind).getSuccessor(kind))
|
||||
else result = getNewInstruction(oldInstruction.getSuccessor(kind))
|
||||
else result = getNewInstruction(oldInstruction.getSuccessor(kind))
|
||||
)
|
||||
)
|
||||
or
|
||||
|
||||
@@ -13,15 +13,3 @@ import semmle.code.cpp.ir.implementation.internal.TOperand::AliasedSsaOperands a
|
||||
|
||||
/** DEPRECATED: Alias for SsaOperands */
|
||||
deprecated module SSAOperands = SsaOperands;
|
||||
|
||||
private import SideEffectElimination as Elim
|
||||
|
||||
predicate removedInstruction(Reachability::ReachableInstruction instr) {
|
||||
Elim::removeableSideEffect(instr)
|
||||
}
|
||||
|
||||
class OldBlock = Reachability::ReachableBlock;
|
||||
|
||||
class OldInstruction extends Reachability::ReachableInstruction {
|
||||
OldInstruction() { not Elim::removeableSideEffect(this) }
|
||||
}
|
||||
|
||||
@@ -1,42 +0,0 @@
|
||||
import cpp as CPP
|
||||
import semmle.code.cpp.ir.implementation.unaliased_ssa.IR as Unaliased
|
||||
import AliasAnalysis as Alias
|
||||
import AliasConfiguration as Conf
|
||||
import semmle.code.cpp.models.interfaces.SideEffect as SideEffect
|
||||
|
||||
private predicate noLocalSideEffectWrite(CPP::Function func) {
|
||||
forall(Unaliased::AddressOperand addr | addr.getUse().getEnclosingFunction() = func |
|
||||
not (
|
||||
Alias::getAddressOperandAllocation(addr) instanceof Conf::VariableAllocation and
|
||||
Alias::getAddressOperandAllocation(addr).(Conf::VariableAllocation).alwaysEscapes()
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
language[monotonicAggregates]
|
||||
private predicate noTransitiveSideEffectWrite(CPP::Function func) {
|
||||
exists(Unaliased::IRFunction irFunc | irFunc.getFunction() = func) and
|
||||
noLocalSideEffectWrite(func) and
|
||||
forall(Unaliased::CallInstruction call | call.getEnclosingFunction() = func |
|
||||
exists(call.getStaticCallTarget())
|
||||
) and
|
||||
forall(Unaliased::CallInstruction call, CPP::Function callee |
|
||||
call.getStaticCallTarget() = callee and
|
||||
call.getEnclosingFunction() = func
|
||||
|
|
||||
noTransitiveSideEffectWrite(callee)
|
||||
or
|
||||
callee.(SideEffect::SideEffectFunction).hasOnlySpecificWriteSideEffects()
|
||||
)
|
||||
}
|
||||
|
||||
predicate removeableSideEffect(Unaliased::SideEffectInstruction instr) {
|
||||
(
|
||||
instr instanceof Unaliased::CallSideEffectInstruction or
|
||||
instr instanceof Unaliased::CallReadSideEffectInstruction
|
||||
) and
|
||||
noTransitiveSideEffectWrite(instr
|
||||
.getPrimaryInstruction()
|
||||
.(Unaliased::CallInstruction)
|
||||
.getStaticCallTarget())
|
||||
}
|
||||
@@ -34,7 +34,6 @@ newtype TInstruction =
|
||||
AliasedSsa::SSA::hasPhiInstruction(blockStartInstr, memoryLocation)
|
||||
} or
|
||||
TAliasedSsaChiInstruction(TRawInstruction primaryInstruction) {
|
||||
not AliasedSsa::removedInstruction(primaryInstruction) and
|
||||
AliasedSsa::SSA::hasChiInstruction(primaryInstruction)
|
||||
} or
|
||||
TAliasedSsaUnreachedInstruction(IRFunctionBase irFunc) {
|
||||
|
||||
@@ -5,5 +5,3 @@ import semmle.code.cpp.ir.implementation.aliased_ssa.internal.SSAConstruction as
|
||||
|
||||
/** DEPRECATED: Alias for AliasedSsa */
|
||||
deprecated module AliasedSSA = AliasedSsa;
|
||||
|
||||
import semmle.code.cpp.ir.implementation.aliased_ssa.internal.SideEffectElimination as Elim
|
||||
|
||||
@@ -1712,11 +1712,6 @@ class SideEffectInstruction extends Instruction {
|
||||
*/
|
||||
class CallSideEffectInstruction extends SideEffectInstruction {
|
||||
CallSideEffectInstruction() { this.getOpcode() instanceof Opcode::CallSideEffect }
|
||||
|
||||
/** Gets the operand for the value that will be read by this instruction */
|
||||
final SideEffectOperand getSideEffectOperand() { result = this.getAnOperand() }
|
||||
|
||||
final Instruction getSideEffect() { result = this.getAnOperand().getDef() }
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1728,11 +1723,6 @@ class CallSideEffectInstruction extends SideEffectInstruction {
|
||||
*/
|
||||
class CallReadSideEffectInstruction extends SideEffectInstruction {
|
||||
CallReadSideEffectInstruction() { this.getOpcode() instanceof Opcode::CallReadSideEffect }
|
||||
|
||||
/** Gets the operand for the value that will be read by this instruction */
|
||||
final SideEffectOperand getSideEffectOperand() { result = this.getAnOperand() }
|
||||
|
||||
final Instruction getSideEffect() { result = this.getAnOperand().getDef() }
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import semmle.code.cpp.ir.implementation.aliased_ssa.IR
|
||||
import semmle.code.cpp.ir.internal.Overlap
|
||||
import semmle.code.cpp.ir.internal.IRCppLanguage as Language
|
||||
import semmle.code.cpp.models.interfaces.SideEffect as SideEffect
|
||||
|
||||
@@ -41,92 +41,8 @@ newtype TValueNumber =
|
||||
) {
|
||||
loadTotalOverlapValueNumber(_, irFunc, type, memOperand, operand)
|
||||
} or
|
||||
TCallValueNumber(TCallPartialValueNumber vn) { callValueNumber(_, _, vn) } or
|
||||
TUniqueValueNumber(IRFunction irFunc, Instruction instr) { uniqueValueNumber(instr, irFunc) }
|
||||
|
||||
private class NumberableCallInstruction extends CallInstruction {
|
||||
NumberableCallInstruction() {
|
||||
not this.getResultIRType() instanceof IRVoidType and
|
||||
exists(SideEffect::SideEffectFunction sideEffectFunc |
|
||||
sideEffectFunc = this.getStaticCallTarget()
|
||||
|
|
||||
sideEffectFunc.hasOnlySpecificReadSideEffects() and
|
||||
sideEffectFunc.hasOnlySpecificWriteSideEffects()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private newtype TCallPartialValueNumber =
|
||||
TNilArgument() or
|
||||
TArgument(TCallPartialValueNumber head, TValueNumber arg) {
|
||||
exists(NumberableCallInstruction call, int index |
|
||||
callArgValueNumber(call, index, arg) and
|
||||
callPartialValueNumber(call, index, head)
|
||||
)
|
||||
}
|
||||
|
||||
private predicate callValueNumber(
|
||||
NumberableCallInstruction call, int index, TCallPartialValueNumber vn
|
||||
) {
|
||||
index = max(int n | callArgRank(call, n, _) | n) and
|
||||
exists(TCallPartialValueNumber head, TValueNumber arg |
|
||||
callPartialValueNumber(call, index, pragma[only_bind_out](head)) and
|
||||
callArgValueNumber(call, index, pragma[only_bind_into](arg)) and
|
||||
vn = TArgument(head, arg)
|
||||
)
|
||||
or
|
||||
not exists(int n | callArgRank(call, n, _)) and
|
||||
index = -1 and
|
||||
vn = TNilArgument()
|
||||
}
|
||||
|
||||
private predicate callPartialValueNumber(
|
||||
NumberableCallInstruction call, int index, TCallPartialValueNumber head
|
||||
) {
|
||||
exists(call) and
|
||||
index = 1 and
|
||||
head = TNilArgument()
|
||||
or
|
||||
exists(TCallPartialValueNumber prev, TValueNumber prevVN |
|
||||
callPartialValueNumber(call, index - 1, pragma[only_bind_out](prev)) and
|
||||
callArgValueNumber(call, index - 1, pragma[only_bind_into](prevVN)) and
|
||||
head = TArgument(prev, prevVN)
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
*/
|
||||
private predicate callArgValueNumber(NumberableCallInstruction call, int index, TValueNumber arg) {
|
||||
exists(Instruction instr |
|
||||
callArgRank(call, index, instr) and
|
||||
arg = tvalueNumber(instr)
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if `arg` is the `index`th element in `call`'s extended argument list, including the `this`
|
||||
* argument and side-effect reads.
|
||||
*/
|
||||
private predicate callArgRank(NumberableCallInstruction call, int index, Instruction arg) {
|
||||
arg =
|
||||
rank[index](int argIndex, boolean isEffect, Instruction instr |
|
||||
// There is no need to include the call's read and write side effects on
|
||||
// all-aliased-memory as `NumberableCallInstruction`s do not read or write
|
||||
// to all-aliased-memory.
|
||||
instr = call.getArgument(argIndex) and
|
||||
isEffect = false
|
||||
or
|
||||
exists(ReadSideEffectInstruction read |
|
||||
read.getPrimaryInstruction() = call and
|
||||
read.getSideEffectOperand().getAnyDef() = instr and
|
||||
read.getIndex() = argIndex and
|
||||
isEffect = true
|
||||
)
|
||||
|
|
||||
instr order by argIndex, isEffect
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* A `CopyInstruction` whose source operand's value is congruent to the definition of that source
|
||||
* operand.
|
||||
@@ -177,8 +93,6 @@ private predicate numberableInstruction(Instruction instr) {
|
||||
instr instanceof CongruentCopyInstruction
|
||||
or
|
||||
instr instanceof LoadTotalOverlapInstruction
|
||||
or
|
||||
instr instanceof NumberableCallInstruction
|
||||
}
|
||||
|
||||
private predicate filteredNumberableInstruction(Instruction instr) {
|
||||
@@ -395,11 +309,6 @@ private TValueNumber nonUniqueValueNumber(Instruction instr) {
|
||||
or
|
||||
// The value number of a copy is just the value number of its source value.
|
||||
result = tvalueNumber(instr.(CongruentCopyInstruction).getSourceValue())
|
||||
or
|
||||
exists(TCallPartialValueNumber pvn |
|
||||
callValueNumber(instr, _, pvn) and
|
||||
result = TCallValueNumber(pvn)
|
||||
)
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1712,11 +1712,6 @@ class SideEffectInstruction extends Instruction {
|
||||
*/
|
||||
class CallSideEffectInstruction extends SideEffectInstruction {
|
||||
CallSideEffectInstruction() { this.getOpcode() instanceof Opcode::CallSideEffect }
|
||||
|
||||
/** Gets the operand for the value that will be read by this instruction */
|
||||
final SideEffectOperand getSideEffectOperand() { result = this.getAnOperand() }
|
||||
|
||||
final Instruction getSideEffect() { result = this.getAnOperand().getDef() }
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1728,11 +1723,6 @@ class CallSideEffectInstruction extends SideEffectInstruction {
|
||||
*/
|
||||
class CallReadSideEffectInstruction extends SideEffectInstruction {
|
||||
CallReadSideEffectInstruction() { this.getOpcode() instanceof Opcode::CallReadSideEffect }
|
||||
|
||||
/** Gets the operand for the value that will be read by this instruction */
|
||||
final SideEffectOperand getSideEffectOperand() { result = this.getAnOperand() }
|
||||
|
||||
final Instruction getSideEffect() { result = this.getAnOperand().getDef() }
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import semmle.code.cpp.ir.implementation.aliased_ssa.IR
|
||||
import semmle.code.cpp.ir.internal.Overlap
|
||||
import semmle.code.cpp.ir.internal.IRCppLanguage as Language
|
||||
import semmle.code.cpp.models.interfaces.SideEffect as SideEffect
|
||||
|
||||
@@ -41,92 +41,8 @@ newtype TValueNumber =
|
||||
) {
|
||||
loadTotalOverlapValueNumber(_, irFunc, type, memOperand, operand)
|
||||
} or
|
||||
TCallValueNumber(TCallPartialValueNumber vn) { callValueNumber(_, _, vn) } or
|
||||
TUniqueValueNumber(IRFunction irFunc, Instruction instr) { uniqueValueNumber(instr, irFunc) }
|
||||
|
||||
private class NumberableCallInstruction extends CallInstruction {
|
||||
NumberableCallInstruction() {
|
||||
not this.getResultIRType() instanceof IRVoidType and
|
||||
exists(SideEffect::SideEffectFunction sideEffectFunc |
|
||||
sideEffectFunc = this.getStaticCallTarget()
|
||||
|
|
||||
sideEffectFunc.hasOnlySpecificReadSideEffects() and
|
||||
sideEffectFunc.hasOnlySpecificWriteSideEffects()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private newtype TCallPartialValueNumber =
|
||||
TNilArgument() or
|
||||
TArgument(TCallPartialValueNumber head, TValueNumber arg) {
|
||||
exists(NumberableCallInstruction call, int index |
|
||||
callArgValueNumber(call, index, arg) and
|
||||
callPartialValueNumber(call, index, head)
|
||||
)
|
||||
}
|
||||
|
||||
private predicate callValueNumber(
|
||||
NumberableCallInstruction call, int index, TCallPartialValueNumber vn
|
||||
) {
|
||||
index = max(int n | callArgRank(call, n, _) | n) and
|
||||
exists(TCallPartialValueNumber head, TValueNumber arg |
|
||||
callPartialValueNumber(call, index, pragma[only_bind_out](head)) and
|
||||
callArgValueNumber(call, index, pragma[only_bind_into](arg)) and
|
||||
vn = TArgument(head, arg)
|
||||
)
|
||||
or
|
||||
not exists(int n | callArgRank(call, n, _)) and
|
||||
index = -1 and
|
||||
vn = TNilArgument()
|
||||
}
|
||||
|
||||
private predicate callPartialValueNumber(
|
||||
NumberableCallInstruction call, int index, TCallPartialValueNumber head
|
||||
) {
|
||||
exists(call) and
|
||||
index = 1 and
|
||||
head = TNilArgument()
|
||||
or
|
||||
exists(TCallPartialValueNumber prev, TValueNumber prevVN |
|
||||
callPartialValueNumber(call, index - 1, pragma[only_bind_out](prev)) and
|
||||
callArgValueNumber(call, index - 1, pragma[only_bind_into](prevVN)) and
|
||||
head = TArgument(prev, prevVN)
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
*/
|
||||
private predicate callArgValueNumber(NumberableCallInstruction call, int index, TValueNumber arg) {
|
||||
exists(Instruction instr |
|
||||
callArgRank(call, index, instr) and
|
||||
arg = tvalueNumber(instr)
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if `arg` is the `index`th element in `call`'s extended argument list, including the `this`
|
||||
* argument and side-effect reads.
|
||||
*/
|
||||
private predicate callArgRank(NumberableCallInstruction call, int index, Instruction arg) {
|
||||
arg =
|
||||
rank[index](int argIndex, boolean isEffect, Instruction instr |
|
||||
// There is no need to include the call's read and write side effects on
|
||||
// all-aliased-memory as `NumberableCallInstruction`s do not read or write
|
||||
// to all-aliased-memory.
|
||||
instr = call.getArgument(argIndex) and
|
||||
isEffect = false
|
||||
or
|
||||
exists(ReadSideEffectInstruction read |
|
||||
read.getPrimaryInstruction() = call and
|
||||
read.getSideEffectOperand().getAnyDef() = instr and
|
||||
read.getIndex() = argIndex and
|
||||
isEffect = true
|
||||
)
|
||||
|
|
||||
instr order by argIndex, isEffect
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* A `CopyInstruction` whose source operand's value is congruent to the definition of that source
|
||||
* operand.
|
||||
@@ -177,8 +93,6 @@ private predicate numberableInstruction(Instruction instr) {
|
||||
instr instanceof CongruentCopyInstruction
|
||||
or
|
||||
instr instanceof LoadTotalOverlapInstruction
|
||||
or
|
||||
instr instanceof NumberableCallInstruction
|
||||
}
|
||||
|
||||
private predicate filteredNumberableInstruction(Instruction instr) {
|
||||
@@ -395,11 +309,6 @@ private TValueNumber nonUniqueValueNumber(Instruction instr) {
|
||||
or
|
||||
// The value number of a copy is just the value number of its source value.
|
||||
result = tvalueNumber(instr.(CongruentCopyInstruction).getSourceValue())
|
||||
or
|
||||
exists(TCallPartialValueNumber pvn |
|
||||
callValueNumber(instr, _, pvn) and
|
||||
result = TCallValueNumber(pvn)
|
||||
)
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -8,6 +8,11 @@ private import Imports::RawIR as RawIR
|
||||
private import SsaInstructions
|
||||
private import SsaOperands
|
||||
private import NewIR
|
||||
|
||||
private class OldBlock = Reachability::ReachableBlock;
|
||||
|
||||
private class OldInstruction = Reachability::ReachableInstruction;
|
||||
|
||||
import Cached
|
||||
|
||||
cached
|
||||
@@ -53,9 +58,7 @@ private module Cached {
|
||||
|
||||
cached
|
||||
predicate hasInstruction(TStageInstruction instr) {
|
||||
instr instanceof TRawInstruction and
|
||||
instr instanceof OldInstruction and
|
||||
not removedInstruction(instr)
|
||||
instr instanceof TRawInstruction and instr instanceof OldInstruction
|
||||
or
|
||||
instr = phiInstruction(_, _)
|
||||
or
|
||||
@@ -379,14 +382,7 @@ private module Cached {
|
||||
(
|
||||
if Reachability::isInfeasibleInstructionSuccessor(oldInstruction, kind)
|
||||
then result = unreachedInstruction(instruction.getEnclosingIRFunction())
|
||||
else
|
||||
if removedInstruction(oldInstruction.getSuccessor(kind))
|
||||
then
|
||||
// the only removed nodes are side-effect writes, but those may have Chi nodes
|
||||
// skip to the following instruction in the old IR, which won't be removed
|
||||
// if we start skipping specific side effects, this may no longer hold
|
||||
result = getNewInstruction(oldInstruction.getSuccessor(kind).getSuccessor(kind))
|
||||
else result = getNewInstruction(oldInstruction.getSuccessor(kind))
|
||||
else result = getNewInstruction(oldInstruction.getSuccessor(kind))
|
||||
)
|
||||
)
|
||||
or
|
||||
|
||||
@@ -14,9 +14,3 @@ import semmle.code.cpp.ir.implementation.internal.TOperand::UnaliasedSsaOperands
|
||||
|
||||
/** DEPRECATED: Alias for SsaOperands */
|
||||
deprecated module SSAOperands = SsaOperands;
|
||||
|
||||
predicate removedInstruction(Reachability::ReachableInstruction instr) { none() }
|
||||
|
||||
class OldBlock = Reachability::ReachableBlock;
|
||||
|
||||
class OldInstruction = Reachability::ReachableInstruction;
|
||||
|
||||
@@ -165,7 +165,7 @@ private ControlFlowNode mostRecentSideEffect(ControlFlowNode node) {
|
||||
|
||||
/** Used to represent the "global value number" of an expression. */
|
||||
cached
|
||||
private newtype GVNBase =
|
||||
private newtype GvnBase =
|
||||
GVN_IntConst(int val, Type t) { mk_IntConst(val, t, _) } or
|
||||
GVN_FloatConst(float val, Type t) { mk_FloatConst(val, t, _) } or
|
||||
// If the local variable does not have a defining value, then
|
||||
@@ -221,8 +221,8 @@ private newtype GVNBase =
|
||||
* expression with this `GVN` and using its `toString` and `getLocation`
|
||||
* methods.
|
||||
*/
|
||||
class GVN extends GVNBase {
|
||||
GVN() { this instanceof GVNBase }
|
||||
class GVN extends GvnBase {
|
||||
GVN() { this instanceof GvnBase }
|
||||
|
||||
/** Gets an expression that has this GVN. */
|
||||
Expr getAnExpr() { this = globalValueNumber(result) }
|
||||
|
||||
@@ -63,17 +63,17 @@ class VariableDeclarationLine extends TVariableDeclarationInfo {
|
||||
/**
|
||||
* Gets a `VariableDeclarationEntry` on this line.
|
||||
*/
|
||||
VariableDeclarationEntry getAVDE() { vdeInfo(result, c, f, line) }
|
||||
VariableDeclarationEntry getAVde() { vdeInfo(result, c, f, line) }
|
||||
|
||||
/**
|
||||
* Gets the start column of the first `VariableDeclarationEntry` on this line.
|
||||
*/
|
||||
int getStartColumn() { result = min(this.getAVDE().getLocation().getStartColumn()) }
|
||||
int getStartColumn() { result = min(this.getAVde().getLocation().getStartColumn()) }
|
||||
|
||||
/**
|
||||
* Gets the end column of the last `VariableDeclarationEntry` on this line.
|
||||
*/
|
||||
int getEndColumn() { result = max(this.getAVDE().getLocation().getEndColumn()) }
|
||||
int getEndColumn() { result = max(this.getAVde().getLocation().getEndColumn()) }
|
||||
|
||||
/**
|
||||
* Gets the rank of this `VariableDeclarationLine` in its file and class
|
||||
@@ -134,13 +134,13 @@ class VariableDeclarationGroup extends VariableDeclarationLine {
|
||||
count(VariableDeclarationLine l |
|
||||
l = this.getProximateNext*()
|
||||
|
|
||||
l.getAVDE().getVariable().getName()
|
||||
l.getAVde().getVariable().getName()
|
||||
)
|
||||
}
|
||||
|
||||
override string toString() {
|
||||
this.getCount() = 1 and
|
||||
result = "declaration of " + this.getAVDE().getVariable().getName()
|
||||
result = "declaration of " + this.getAVde().getVariable().getName()
|
||||
or
|
||||
this.getCount() > 1 and
|
||||
result = "group of " + this.getCount() + " fields here"
|
||||
|
||||
@@ -16,7 +16,7 @@ import cpp
|
||||
class JumpTarget extends Stmt {
|
||||
JumpTarget() { exists(GotoStmt g | g.getTarget() = this) }
|
||||
|
||||
FunctionDeclarationEntry getFDE() { result.getBlock() = this.getParentStmt+() }
|
||||
FunctionDeclarationEntry getFde() { result.getBlock() = this.getParentStmt+() }
|
||||
|
||||
predicate isForward() {
|
||||
exists(GotoStmt g | g.getTarget() = this |
|
||||
@@ -33,8 +33,8 @@ class JumpTarget extends Stmt {
|
||||
|
||||
from FunctionDeclarationEntry fde, int nforward, int nbackward
|
||||
where
|
||||
nforward = strictcount(JumpTarget t | t.getFDE() = fde and t.isForward()) and
|
||||
nbackward = strictcount(JumpTarget t | t.getFDE() = fde and t.isBackward()) and
|
||||
nforward = strictcount(JumpTarget t | t.getFde() = fde and t.isForward()) and
|
||||
nbackward = strictcount(JumpTarget t | t.getFde() = fde and t.isBackward()) and
|
||||
nforward != 1 and
|
||||
nbackward != 1
|
||||
select fde,
|
||||
|
||||
@@ -1,3 +1,9 @@
|
||||
## 0.3.3
|
||||
|
||||
### Minor Analysis Improvements
|
||||
|
||||
* The "Cleartext storage of sensitive information in buffer" (`cpp/cleartext-storage-buffer`) query has been improved to produce fewer false positives.
|
||||
|
||||
## 0.3.2
|
||||
|
||||
### Minor Analysis Improvements
|
||||
|
||||
17
cpp/ql/src/Critical/MissingCheckScanf.cpp
Normal file
17
cpp/ql/src/Critical/MissingCheckScanf.cpp
Normal file
@@ -0,0 +1,17 @@
|
||||
{
|
||||
int i, j, r;
|
||||
|
||||
r = scanf("%d %d", &i, &j);
|
||||
|
||||
use(i); // BAD: i is not guarded
|
||||
|
||||
if (r >= 1) {
|
||||
use(i); // GOOD: i is guarded correctly
|
||||
use(j); // BAD: j is guarded incorrectly
|
||||
}
|
||||
|
||||
if (r != 2)
|
||||
return;
|
||||
|
||||
use(j); // GOOD: j is guarded correctly
|
||||
}
|
||||
51
cpp/ql/src/Critical/MissingCheckScanf.qhelp
Normal file
51
cpp/ql/src/Critical/MissingCheckScanf.qhelp
Normal file
@@ -0,0 +1,51 @@
|
||||
<!DOCTYPE qhelp PUBLIC
|
||||
"-//Semmle//qhelp//EN"
|
||||
"qhelp.dtd">
|
||||
<qhelp>
|
||||
|
||||
|
||||
<overview>
|
||||
<p>
|
||||
This query finds calls of <tt>scanf</tt>-like functions with missing or
|
||||
improper return-value checking.
|
||||
</p>
|
||||
<p>
|
||||
Specifically, the query flags uses of variables that may have been modified by
|
||||
<tt>scanf</tt> and subsequently are used without being guarded by a correct
|
||||
return-value check. A proper check is one that ensures that the corresponding
|
||||
<tt>scanf</tt> has returned (at least) a certain minimum constant.
|
||||
</p>
|
||||
<p>
|
||||
Functions in the <tt>scanf</tt> family return either EOF (a negative value)
|
||||
in case of IO failure, or the number of items successfully read from the
|
||||
input. Consequently, a simple check that the return value is truthy (nonzero)
|
||||
is not enough.
|
||||
</p>
|
||||
<warning>
|
||||
This query has medium precision because, in the current implementation, it
|
||||
takes a strict stance on unguarded uses of output variables, and flags them
|
||||
as problematic even if they have already been initialized.
|
||||
</warning>
|
||||
</overview>
|
||||
|
||||
<recommendation>
|
||||
<p>
|
||||
Ensure that all subsequent uses of <tt>scanf</tt> output arguments occur in a
|
||||
branch of an <tt>if</tt> statement (or similar), in which it is known that the
|
||||
corresponding <tt>scanf</tt> call has in fact read all possible items from its
|
||||
input. This can be done by comparing the return value to a numerical constant.
|
||||
</p>
|
||||
</recommendation>
|
||||
|
||||
<example>
|
||||
<p>This example shows different ways of guarding a <tt>scanf</tt> output:
|
||||
</p>
|
||||
<sample src="MissingCheckScanf.cpp" />
|
||||
</example>
|
||||
|
||||
<references>
|
||||
<li>SEI CERT C++ Coding Standard: <a href="https://wiki.sei.cmu.edu/confluence/display/cplusplus/ERR62-CPP.+Detect+errors+when+converting+a+string+to+a+number">ERR62-CPP. Detect errors when converting a string to a number</a>.</li>
|
||||
<li>SEI CERT C Coding Standard: <a href="https://wiki.sei.cmu.edu/confluence/display/c/ERR33-C.+Detect+and+handle+standard+library+errors">ERR33-C. Detect and handle standard library errors</a>.</li>
|
||||
<li>cppreference.com: <a href="https://en.cppreference.com/w/c/io/fscanf">scanf, fscanf, sscanf, scanf_s, fscanf_s, sscanf_s</a>.</li>
|
||||
</references>
|
||||
</qhelp>
|
||||
122
cpp/ql/src/Critical/MissingCheckScanf.ql
Normal file
122
cpp/ql/src/Critical/MissingCheckScanf.ql
Normal file
@@ -0,0 +1,122 @@
|
||||
/**
|
||||
* @name Missing return-value check for a 'scanf'-like function
|
||||
* @description Failing to check that a call to 'scanf' actually writes to an
|
||||
* output variable can lead to unexpected behavior at reading time.
|
||||
* @kind problem
|
||||
* @problem.severity warning
|
||||
* @security-severity 7.5
|
||||
* @precision medium
|
||||
* @id cpp/missing-check-scanf
|
||||
* @tags security
|
||||
* correctness
|
||||
* external/cwe/cwe-252
|
||||
* external/cwe/cwe-253
|
||||
*/
|
||||
|
||||
import cpp
|
||||
import semmle.code.cpp.commons.Scanf
|
||||
import semmle.code.cpp.controlflow.Guards
|
||||
import semmle.code.cpp.dataflow.DataFlow
|
||||
import semmle.code.cpp.ir.IR
|
||||
import semmle.code.cpp.ir.ValueNumbering
|
||||
|
||||
/** An expression appearing as an output argument to a `scanf`-like call */
|
||||
class ScanfOutput extends Expr {
|
||||
ScanfFunctionCall call;
|
||||
int varargIndex;
|
||||
Instruction instr;
|
||||
ValueNumber valNum;
|
||||
|
||||
ScanfOutput() {
|
||||
this = call.getOutputArgument(varargIndex).getFullyConverted() and
|
||||
instr.getConvertedResultExpression() = this and
|
||||
valueNumber(instr) = valNum
|
||||
}
|
||||
|
||||
ScanfFunctionCall getCall() { result = call }
|
||||
|
||||
/**
|
||||
* Returns the smallest possible `scanf` return value that would indicate
|
||||
* success in writing this output argument.
|
||||
*/
|
||||
int getMinimumGuardConstant() {
|
||||
result =
|
||||
varargIndex + 1 -
|
||||
count(ScanfFormatLiteral f, int n |
|
||||
// Special case: %n writes to an argument without reading any input.
|
||||
// It does not increase the count returned by `scanf`.
|
||||
n <= varargIndex and f.getUse() = call and f.getConversionChar(n) = "n"
|
||||
)
|
||||
}
|
||||
|
||||
predicate hasGuardedAccess(Access e, boolean isGuarded) {
|
||||
e = this.getAnAccess() and
|
||||
if
|
||||
exists(int value, int minGuard | minGuard = this.getMinimumGuardConstant() |
|
||||
e.getBasicBlock() = blockGuardedBy(value, "==", call) and minGuard <= value
|
||||
or
|
||||
e.getBasicBlock() = blockGuardedBy(value, "<", call) and minGuard - 1 <= value
|
||||
or
|
||||
e.getBasicBlock() = blockGuardedBy(value, "<=", call) and minGuard <= value
|
||||
)
|
||||
then isGuarded = true
|
||||
else isGuarded = false
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a subsequent access of the same underlying storage,
|
||||
* but before it gets reset or reused in another `scanf` call.
|
||||
*/
|
||||
Access getAnAccess() {
|
||||
exists(Instruction dst |
|
||||
this.bigStep() = dst and
|
||||
dst.getAst() = result and
|
||||
valueNumber(dst) = valNum
|
||||
)
|
||||
}
|
||||
|
||||
private Instruction bigStep() {
|
||||
result = this.smallStep(instr)
|
||||
or
|
||||
exists(Instruction i | i = this.bigStep() | result = this.smallStep(i))
|
||||
}
|
||||
|
||||
private Instruction smallStep(Instruction i) {
|
||||
instr.getASuccessor*() = i and
|
||||
i.getASuccessor() = result and
|
||||
not this.isBarrier(result)
|
||||
}
|
||||
|
||||
private predicate isBarrier(Instruction i) {
|
||||
valueNumber(i) = valNum and
|
||||
exists(Expr e | i.getAst() = e |
|
||||
i = any(StoreInstruction s).getDestinationAddress()
|
||||
or
|
||||
[e, e.getParent().(AddressOfExpr)] instanceof ScanfOutput
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/** Returns a block guarded by the assertion of `value op call` */
|
||||
BasicBlock blockGuardedBy(int value, string op, ScanfFunctionCall call) {
|
||||
exists(GuardCondition g, Expr left, Expr right |
|
||||
right = g.getAChild() and
|
||||
value = left.getValue().toInt() and
|
||||
DataFlow::localExprFlow(call, right)
|
||||
|
|
||||
g.ensuresEq(left, right, 0, result, true) and op = "=="
|
||||
or
|
||||
g.ensuresLt(left, right, 0, result, true) and op = "<"
|
||||
or
|
||||
g.ensuresLt(left, right, 1, result, true) and op = "<="
|
||||
)
|
||||
}
|
||||
|
||||
from ScanfOutput output, ScanfFunctionCall call, Access access
|
||||
where
|
||||
output.getCall() = call and
|
||||
output.hasGuardedAccess(access, false)
|
||||
select access,
|
||||
"$@ is read here, but may not have been written. " +
|
||||
"It should be guarded by a check that the $@ returns at least " +
|
||||
output.getMinimumGuardConstant() + ".", access, access.toString(), call, call.toString()
|
||||
@@ -13,7 +13,7 @@ import SAL
|
||||
|
||||
from Parameter p, Call c, Expr arg
|
||||
where
|
||||
any(SALNotNull a).getDeclaration() = p and
|
||||
any(SalNotNull a).getDeclaration() = p and
|
||||
c.getTarget() = p.getFunction() and
|
||||
arg = c.getArgument(p.getIndex()) and
|
||||
nullValue(arg)
|
||||
|
||||
@@ -18,7 +18,7 @@ from Function f, FunctionCall call
|
||||
where
|
||||
call.getTarget() = f and
|
||||
call instanceof ExprInVoidContext and
|
||||
any(SALCheckReturn a).getDeclaration() = f and
|
||||
any(SalCheckReturn a).getDeclaration() = f and
|
||||
not getOptions().okToIgnoreReturnValue(call)
|
||||
select call, "Return value of $@ discarded although a SAL annotation " + "requires inspecting it.",
|
||||
f, f.getName()
|
||||
|
||||
@@ -11,7 +11,7 @@ import SAL
|
||||
|
||||
/** Holds if `e` has SAL annotation `name`. */
|
||||
predicate hasAnnotation(DeclarationEntry e, string name) {
|
||||
exists(SALAnnotation a |
|
||||
exists(SalAnnotation a |
|
||||
a.getMacro().getName() = name and
|
||||
a.getDeclarationEntry() = e
|
||||
)
|
||||
@@ -21,7 +21,7 @@ predicate hasAnnotation(DeclarationEntry e, string name) {
|
||||
predicate inheritsDeclAnnotations(DeclarationEntry e) {
|
||||
// Is directly annotated
|
||||
e.isDefinition() and
|
||||
exists(SALAnnotation a | a.getMacro().getName() = "_Use_decl_annotations_" |
|
||||
exists(SalAnnotation a | a.getMacro().getName() = "_Use_decl_annotations_" |
|
||||
a.getDeclarationEntry() = e
|
||||
)
|
||||
or
|
||||
|
||||
@@ -8,8 +8,8 @@ import cpp
|
||||
/**
|
||||
* A SAL macro defined in `sal.h` or a similar header file.
|
||||
*/
|
||||
class SALMacro extends Macro {
|
||||
SALMacro() {
|
||||
class SalMacro extends Macro {
|
||||
SalMacro() {
|
||||
this.getFile().getBaseName() =
|
||||
["sal.h", "specstrings_strict.h", "specstrings.h", "w32p.h", "minwindef.h"] and
|
||||
(
|
||||
@@ -22,15 +22,18 @@ class SALMacro extends Macro {
|
||||
}
|
||||
}
|
||||
|
||||
/** DEPRECATED: Alias for SalMacro */
|
||||
deprecated class SALMacro = SalMacro;
|
||||
|
||||
pragma[noinline]
|
||||
private predicate isTopLevelMacroAccess(MacroAccess ma) { not exists(ma.getParentInvocation()) }
|
||||
|
||||
/**
|
||||
* An invocation of a SAL macro (excluding invocations inside other macros).
|
||||
*/
|
||||
class SALAnnotation extends MacroInvocation {
|
||||
SALAnnotation() {
|
||||
this.getMacro() instanceof SALMacro and
|
||||
class SalAnnotation extends MacroInvocation {
|
||||
SalAnnotation() {
|
||||
this.getMacro() instanceof SalMacro and
|
||||
isTopLevelMacroAccess(this)
|
||||
}
|
||||
|
||||
@@ -47,23 +50,29 @@ class SALAnnotation extends MacroInvocation {
|
||||
}
|
||||
}
|
||||
|
||||
/** DEPRECATED: Alias for SalAnnotation */
|
||||
deprecated class SALAnnotation = SalAnnotation;
|
||||
|
||||
/**
|
||||
* A SAL macro indicating that the return value of a function should always be
|
||||
* checked.
|
||||
*/
|
||||
class SALCheckReturn extends SALAnnotation {
|
||||
SALCheckReturn() {
|
||||
this.getMacro().(SALMacro).getName() = ["_Check_return_", "_Must_inspect_result_"]
|
||||
class SalCheckReturn extends SalAnnotation {
|
||||
SalCheckReturn() {
|
||||
this.getMacro().(SalMacro).getName() = ["_Check_return_", "_Must_inspect_result_"]
|
||||
}
|
||||
}
|
||||
|
||||
/** DEPRECATED: Alias for SalCheckReturn */
|
||||
deprecated class SALCheckReturn = SalCheckReturn;
|
||||
|
||||
/**
|
||||
* A SAL macro indicating that a pointer variable or return value should not be
|
||||
* `NULL`.
|
||||
*/
|
||||
class SALNotNull extends SALAnnotation {
|
||||
SALNotNull() {
|
||||
exists(SALMacro m | m = this.getMacro() |
|
||||
class SalNotNull extends SalAnnotation {
|
||||
SalNotNull() {
|
||||
exists(SalMacro m | m = this.getMacro() |
|
||||
not m.getName().matches("%\\_opt\\_%") and
|
||||
(
|
||||
m.getName().matches("_In%") or
|
||||
@@ -80,12 +89,15 @@ class SALNotNull extends SALAnnotation {
|
||||
}
|
||||
}
|
||||
|
||||
/** DEPRECATED: Alias for SalNotNull */
|
||||
deprecated class SALNotNull = SalNotNull;
|
||||
|
||||
/**
|
||||
* A SAL macro indicating that a value may be `NULL`.
|
||||
*/
|
||||
class SALMaybeNull extends SALAnnotation {
|
||||
SALMaybeNull() {
|
||||
exists(SALMacro m | m = this.getMacro() |
|
||||
class SalMaybeNull extends SalAnnotation {
|
||||
SalMaybeNull() {
|
||||
exists(SalMacro m | m = this.getMacro() |
|
||||
m.getName().matches("%\\_opt\\_%") or
|
||||
m.getName().matches("\\_Ret_maybenull\\_%") or
|
||||
m.getName() = "_Result_nullonfailure_"
|
||||
@@ -93,14 +105,17 @@ class SALMaybeNull extends SALAnnotation {
|
||||
}
|
||||
}
|
||||
|
||||
/** DEPRECATED: Alias for SalMaybeNull */
|
||||
deprecated class SALMaybeNull = SalMaybeNull;
|
||||
|
||||
/**
|
||||
* A parameter annotated by one or more SAL annotations.
|
||||
*/
|
||||
class SALParameter extends Parameter {
|
||||
class SalParameter extends Parameter {
|
||||
/** One of this parameter's annotations. */
|
||||
SALAnnotation a;
|
||||
SalAnnotation a;
|
||||
|
||||
SALParameter() { annotatesAt(a, this.getADeclarationEntry(), _, _) }
|
||||
SalParameter() { annotatesAt(a, this.getADeclarationEntry(), _, _) }
|
||||
|
||||
predicate isIn() { a.getMacroName().toLowerCase().matches("%\\_in%") }
|
||||
|
||||
@@ -109,14 +124,17 @@ class SALParameter extends Parameter {
|
||||
predicate isInOut() { a.getMacroName().toLowerCase().matches("%\\_inout%") }
|
||||
}
|
||||
|
||||
/** DEPRECATED: Alias for SalParameter */
|
||||
deprecated class SALParameter = SalParameter;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Implementation details
|
||||
/**
|
||||
* Holds if `a` annotates the declaration entry `d` and
|
||||
* its start position is the `idx`th position in `file` that holds a SAL element.
|
||||
*/
|
||||
private predicate annotatesAt(SALAnnotation a, DeclarationEntry d, File file, int idx) {
|
||||
annotatesAtPosition(a.(SALElement).getStartPosition(), d, file, idx)
|
||||
private predicate annotatesAt(SalAnnotation a, DeclarationEntry d, File file, int idx) {
|
||||
annotatesAtPosition(a.(SalElement).getStartPosition(), d, file, idx)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -127,12 +145,12 @@ private predicate annotatesAt(SALAnnotation a, DeclarationEntry d, File file, in
|
||||
// For performance reasons, do not mention the annotation itself here,
|
||||
// but compute with positions instead. This performs better on databases
|
||||
// with many annotations at the same position.
|
||||
private predicate annotatesAtPosition(SALPosition pos, DeclarationEntry d, File file, int idx) {
|
||||
private predicate annotatesAtPosition(SalPosition pos, DeclarationEntry d, File file, int idx) {
|
||||
pos = salRelevantPositionAt(file, idx) and
|
||||
salAnnotationPos(pos) and
|
||||
(
|
||||
// Base case: `pos` right before `d`
|
||||
d.(SALElement).getStartPosition() = salRelevantPositionAt(file, idx + 1)
|
||||
d.(SalElement).getStartPosition() = salRelevantPositionAt(file, idx + 1)
|
||||
or
|
||||
// Recursive case: `pos` right before some annotation on `d`
|
||||
annotatesAtPosition(_, d, file, idx + 1)
|
||||
@@ -143,10 +161,10 @@ private predicate annotatesAtPosition(SALPosition pos, DeclarationEntry d, File
|
||||
* A SAL element, that is, a SAL annotation or a declaration entry
|
||||
* that may have SAL annotations.
|
||||
*/
|
||||
library class SALElement extends Element {
|
||||
SALElement() {
|
||||
containsSALAnnotation(this.(DeclarationEntry).getFile()) or
|
||||
this instanceof SALAnnotation
|
||||
library class SalElement extends Element {
|
||||
SalElement() {
|
||||
containsSalAnnotation(this.(DeclarationEntry).getFile()) or
|
||||
this instanceof SalAnnotation
|
||||
}
|
||||
|
||||
predicate hasStartPosition(File file, int line, int col) {
|
||||
@@ -173,25 +191,28 @@ library class SALElement extends Element {
|
||||
)
|
||||
}
|
||||
|
||||
SALPosition getStartPosition() {
|
||||
SalPosition getStartPosition() {
|
||||
exists(File file, int line, int col |
|
||||
this.hasStartPosition(file, line, col) and
|
||||
result = MkSALPosition(file, line, col)
|
||||
result = MkSalPosition(file, line, col)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/** DEPRECATED: Alias for SalElement */
|
||||
deprecated class SALElement = SalElement;
|
||||
|
||||
/** Holds if `file` contains a SAL annotation. */
|
||||
pragma[noinline]
|
||||
private predicate containsSALAnnotation(File file) { any(SALAnnotation a).getFile() = file }
|
||||
private predicate containsSalAnnotation(File file) { any(SalAnnotation a).getFile() = file }
|
||||
|
||||
/**
|
||||
* A source-file position of a `SALElement`. Unlike location, this denotes a
|
||||
* point in the file rather than a range.
|
||||
*/
|
||||
private newtype SALPosition =
|
||||
MkSALPosition(File file, int line, int col) {
|
||||
exists(SALElement e |
|
||||
private newtype SalPosition =
|
||||
MkSalPosition(File file, int line, int col) {
|
||||
exists(SalElement e |
|
||||
e.hasStartPosition(file, line, col)
|
||||
or
|
||||
e.hasEndPosition(file, line, col)
|
||||
@@ -200,18 +221,18 @@ private newtype SALPosition =
|
||||
|
||||
/** Holds if `pos` is the start position of a SAL annotation. */
|
||||
pragma[noinline]
|
||||
private predicate salAnnotationPos(SALPosition pos) {
|
||||
any(SALAnnotation a).(SALElement).getStartPosition() = pos
|
||||
private predicate salAnnotationPos(SalPosition pos) {
|
||||
any(SalAnnotation a).(SalElement).getStartPosition() = pos
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the `idx`th position in `file` that holds a SAL element,
|
||||
* ordering positions lexicographically by their start line and start column.
|
||||
*/
|
||||
private SALPosition salRelevantPositionAt(File file, int idx) {
|
||||
private SalPosition salRelevantPositionAt(File file, int idx) {
|
||||
result =
|
||||
rank[idx](SALPosition pos, int line, int col |
|
||||
pos = MkSALPosition(file, line, col)
|
||||
rank[idx](SalPosition pos, int line, int col |
|
||||
pos = MkSalPosition(file, line, col)
|
||||
|
|
||||
pos order by line, col
|
||||
)
|
||||
|
||||
@@ -24,7 +24,7 @@ where
|
||||
if e = DefinitionInSnapshot()
|
||||
then defined = ""
|
||||
else
|
||||
if e = SuggestiveSALAnnotation()
|
||||
if e = SuggestiveSalAnnotation()
|
||||
then defined = "externally defined (SAL) "
|
||||
else defined = "externally defined (CSV) "
|
||||
)
|
||||
|
||||
@@ -149,7 +149,7 @@ newtype Evidence =
|
||||
* The function is externally defined, but the parameter has an `_out` SAL annotation which
|
||||
* suggests that it is initialized in the function.
|
||||
*/
|
||||
SuggestiveSALAnnotation() or
|
||||
SuggestiveSalAnnotation() or
|
||||
/**
|
||||
* We have been given a CSV file which indicates this parameter is conditionally initialized.
|
||||
*/
|
||||
@@ -198,8 +198,8 @@ class InitializationFunction extends Function {
|
||||
or
|
||||
// If we have no definition, we look at SAL annotations
|
||||
not this.hasDefinition() and
|
||||
this.getParameter(i).(SALParameter).isOut() and
|
||||
evidence = SuggestiveSALAnnotation()
|
||||
this.getParameter(i).(SalParameter).isOut() and
|
||||
evidence = SuggestiveSalAnnotation()
|
||||
or
|
||||
// We have some external information that this function conditionally initializes
|
||||
not this.hasDefinition() and
|
||||
|
||||
@@ -19,8 +19,8 @@ import DataFlow::PathGraph
|
||||
/**
|
||||
* A configuration for tracking XML objects and their states.
|
||||
*/
|
||||
class XXEConfiguration extends DataFlow::Configuration {
|
||||
XXEConfiguration() { this = "XXEConfiguration" }
|
||||
class XxeConfiguration extends DataFlow::Configuration {
|
||||
XxeConfiguration() { this = "XXEConfiguration" }
|
||||
|
||||
override predicate isSource(DataFlow::Node node, string flowstate) {
|
||||
any(XmlLibrary l).configurationSource(node, flowstate)
|
||||
@@ -45,7 +45,7 @@ class XXEConfiguration extends DataFlow::Configuration {
|
||||
}
|
||||
}
|
||||
|
||||
from XXEConfiguration conf, DataFlow::PathNode source, DataFlow::PathNode sink
|
||||
from XxeConfiguration conf, DataFlow::PathNode source, DataFlow::PathNode sink
|
||||
where conf.hasFlowPath(source, sink)
|
||||
select sink, source, sink,
|
||||
"This $@ is not configured to prevent an XML external entity (XXE) attack.", source, "XML parser"
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
---
|
||||
category: newQuery
|
||||
---
|
||||
* Added a new medium-precision query, `cpp/missing-check-scanf`, which detects `scanf` output variables that are used without a proper return-value check to see that they were actually written. A variation of this query was originally contributed as an [experimental query by @ihsinme](https://github.com/github/codeql/pull/8246).
|
||||
@@ -1,4 +1,5 @@
|
||||
---
|
||||
category: minorAnalysis
|
||||
---
|
||||
## 0.3.3
|
||||
|
||||
### Minor Analysis Improvements
|
||||
|
||||
* The "Cleartext storage of sensitive information in buffer" (`cpp/cleartext-storage-buffer`) query has been improved to produce fewer false positives.
|
||||
@@ -1,2 +1,2 @@
|
||||
---
|
||||
lastReleaseVersion: 0.3.2
|
||||
lastReleaseVersion: 0.3.3
|
||||
|
||||
@@ -16,17 +16,17 @@ import cpp
|
||||
// pointers. This will obviously not catch code that uses inline assembly to achieve
|
||||
// self-modification, nor will it spot the use of OS mechanisms to write into process
|
||||
// memory (such as WriteProcessMemory under Windows).
|
||||
predicate maybeSMCConversion(Type t1, Type t2) {
|
||||
predicate maybeSmcConversion(Type t1, Type t2) {
|
||||
t1 instanceof FunctionPointerType and
|
||||
t2 instanceof PointerType and
|
||||
not t2 instanceof FunctionPointerType and
|
||||
not t2 instanceof VoidPointerType
|
||||
or
|
||||
maybeSMCConversion(t2, t1)
|
||||
maybeSmcConversion(t2, t1)
|
||||
}
|
||||
|
||||
from Expr e
|
||||
where
|
||||
e.fromSource() and
|
||||
maybeSMCConversion(e.getUnderlyingType(), e.getActualType())
|
||||
maybeSmcConversion(e.getUnderlyingType(), e.getActualType())
|
||||
select e, "AV Rule 2: There shall not be any self-modifying code."
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
name: codeql/cpp-queries
|
||||
version: 0.3.3-dev
|
||||
version: 0.3.4-dev
|
||||
groups:
|
||||
- cpp
|
||||
- queries
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1050,36 +1050,46 @@ ssa.cpp:
|
||||
# 240| r240_3(glval<unknown>) = FunctionAddress[Constructible] :
|
||||
# 240| r240_4(int) = Constant[1] :
|
||||
# 240| v240_5(void) = Call[Constructible] : func:r240_3, this:r240_1, 0:r240_4
|
||||
# 240| m240_6(Constructible) = ^IndirectMayWriteSideEffect[-1] : &:r240_1
|
||||
# 240| m240_7(Constructible) = Chi : total:m240_2, partial:m240_6
|
||||
# 240| m240_6(unknown) = ^CallSideEffect : ~m239_4
|
||||
# 240| m240_7(unknown) = Chi : total:m239_4, partial:m240_6
|
||||
# 240| m240_8(Constructible) = ^IndirectMayWriteSideEffect[-1] : &:r240_1
|
||||
# 240| m240_9(Constructible) = Chi : total:m240_2, partial:m240_8
|
||||
# 241| r241_1(glval<Constructible>) = VariableAddress[c] :
|
||||
# 241| r241_2(glval<unknown>) = FunctionAddress[g] :
|
||||
# 241| v241_3(void) = Call[g] : func:r241_2, this:r241_1
|
||||
# 241| v241_4(void) = ^IndirectReadSideEffect[-1] : &:r241_1, m240_7
|
||||
# 241| m241_5(Constructible) = ^IndirectMayWriteSideEffect[-1] : &:r241_1
|
||||
# 241| m241_6(Constructible) = Chi : total:m240_7, partial:m241_5
|
||||
# 241| m241_4(unknown) = ^CallSideEffect : ~m240_7
|
||||
# 241| m241_5(unknown) = Chi : total:m240_7, partial:m241_4
|
||||
# 241| v241_6(void) = ^IndirectReadSideEffect[-1] : &:r241_1, m240_9
|
||||
# 241| m241_7(Constructible) = ^IndirectMayWriteSideEffect[-1] : &:r241_1
|
||||
# 241| m241_8(Constructible) = Chi : total:m240_9, partial:m241_7
|
||||
# 242| r242_1(glval<Constructible>) = VariableAddress[c] :
|
||||
# 242| r242_2(glval<unknown>) = FunctionAddress[g] :
|
||||
# 242| v242_3(void) = Call[g] : func:r242_2, this:r242_1
|
||||
# 242| v242_4(void) = ^IndirectReadSideEffect[-1] : &:r242_1, m241_6
|
||||
# 242| m242_5(Constructible) = ^IndirectMayWriteSideEffect[-1] : &:r242_1
|
||||
# 242| m242_6(Constructible) = Chi : total:m241_6, partial:m242_5
|
||||
# 242| m242_4(unknown) = ^CallSideEffect : ~m241_5
|
||||
# 242| m242_5(unknown) = Chi : total:m241_5, partial:m242_4
|
||||
# 242| v242_6(void) = ^IndirectReadSideEffect[-1] : &:r242_1, m241_8
|
||||
# 242| m242_7(Constructible) = ^IndirectMayWriteSideEffect[-1] : &:r242_1
|
||||
# 242| m242_8(Constructible) = Chi : total:m241_8, partial:m242_7
|
||||
# 243| r243_1(glval<Constructible>) = VariableAddress[c2] :
|
||||
# 243| m243_2(Constructible) = Uninitialized[c2] : &:r243_1
|
||||
# 243| r243_3(glval<unknown>) = FunctionAddress[Constructible] :
|
||||
# 243| r243_4(int) = Constant[2] :
|
||||
# 243| v243_5(void) = Call[Constructible] : func:r243_3, this:r243_1, 0:r243_4
|
||||
# 243| m243_6(Constructible) = ^IndirectMayWriteSideEffect[-1] : &:r243_1
|
||||
# 243| m243_7(Constructible) = Chi : total:m243_2, partial:m243_6
|
||||
# 243| m243_6(unknown) = ^CallSideEffect : ~m242_5
|
||||
# 243| m243_7(unknown) = Chi : total:m242_5, partial:m243_6
|
||||
# 243| m243_8(Constructible) = ^IndirectMayWriteSideEffect[-1] : &:r243_1
|
||||
# 243| m243_9(Constructible) = Chi : total:m243_2, partial:m243_8
|
||||
# 244| r244_1(glval<Constructible>) = VariableAddress[c2] :
|
||||
# 244| r244_2(glval<unknown>) = FunctionAddress[g] :
|
||||
# 244| v244_3(void) = Call[g] : func:r244_2, this:r244_1
|
||||
# 244| v244_4(void) = ^IndirectReadSideEffect[-1] : &:r244_1, m243_7
|
||||
# 244| m244_5(Constructible) = ^IndirectMayWriteSideEffect[-1] : &:r244_1
|
||||
# 244| m244_6(Constructible) = Chi : total:m243_7, partial:m244_5
|
||||
# 244| m244_4(unknown) = ^CallSideEffect : ~m243_7
|
||||
# 244| m244_5(unknown) = Chi : total:m243_7, partial:m244_4
|
||||
# 244| v244_6(void) = ^IndirectReadSideEffect[-1] : &:r244_1, m243_9
|
||||
# 244| m244_7(Constructible) = ^IndirectMayWriteSideEffect[-1] : &:r244_1
|
||||
# 244| m244_8(Constructible) = Chi : total:m243_9, partial:m244_7
|
||||
# 245| v245_1(void) = NoOp :
|
||||
# 239| v239_5(void) = ReturnVoid :
|
||||
# 239| v239_6(void) = AliasedUse : m239_3
|
||||
# 239| v239_6(void) = AliasedUse : ~m244_5
|
||||
# 239| v239_7(void) = ExitFunction :
|
||||
|
||||
# 247| char* VoidStarIndirectParameters(char*, int)
|
||||
@@ -1381,37 +1391,43 @@ ssa.cpp:
|
||||
# 294| r294_18(glval<int>) = VariableAddress[x] :
|
||||
# 294| r294_19(int) = Load[x] : &:r294_18, m291_6
|
||||
# 294| v294_20(void) = Call[A] : func:r294_17, this:r294_16, 0:r294_19
|
||||
# 294| m294_21(A) = ^IndirectMayWriteSideEffect[-1] : &:r294_16
|
||||
# 294| m294_22(unknown) = Chi : total:m294_15, partial:m294_21
|
||||
# 294| v294_23(void) = Call[A] : func:r294_9, this:r294_8, 0:r294_16
|
||||
# 294| v294_24(void) = ^BufferReadSideEffect[0] : &:r294_16, ~m294_22
|
||||
# 294| m294_25(A) = ^IndirectMayWriteSideEffect[-1] : &:r294_8
|
||||
# 294| m294_26(unknown) = Chi : total:m294_7, partial:m294_25
|
||||
# 294| m294_27(unknown) = ^BufferMayWriteSideEffect[0] : &:r294_16
|
||||
# 294| m294_28(unknown) = Chi : total:m294_22, partial:m294_27
|
||||
# 294| r294_29(glval<int>) = FieldAddress[i] : r294_8
|
||||
# 294| r294_30(int) = Load[?] : &:r294_29, ~m294_26
|
||||
# 294| m294_31(int) = Store[j] : &:r294_1, r294_30
|
||||
# 294| m294_21(unknown) = ^CallSideEffect : ~m294_14
|
||||
# 294| m294_22(unknown) = Chi : total:m294_14, partial:m294_21
|
||||
# 294| m294_23(A) = ^IndirectMayWriteSideEffect[-1] : &:r294_16
|
||||
# 294| m294_24(unknown) = Chi : total:m294_15, partial:m294_23
|
||||
# 294| v294_25(void) = Call[A] : func:r294_9, this:r294_8, 0:r294_16
|
||||
# 294| m294_26(unknown) = ^CallSideEffect : ~m294_22
|
||||
# 294| m294_27(unknown) = Chi : total:m294_22, partial:m294_26
|
||||
# 294| v294_28(void) = ^BufferReadSideEffect[0] : &:r294_16, ~m294_24
|
||||
# 294| m294_29(A) = ^IndirectMayWriteSideEffect[-1] : &:r294_8
|
||||
# 294| m294_30(unknown) = Chi : total:m294_7, partial:m294_29
|
||||
# 294| m294_31(unknown) = ^BufferMayWriteSideEffect[0] : &:r294_16
|
||||
# 294| m294_32(unknown) = Chi : total:m294_24, partial:m294_31
|
||||
# 294| r294_33(glval<int>) = FieldAddress[i] : r294_8
|
||||
# 294| r294_34(int) = Load[?] : &:r294_33, ~m294_30
|
||||
# 294| m294_35(int) = Store[j] : &:r294_1, r294_34
|
||||
# 295| r295_1(glval<A *>) = VariableAddress[a] :
|
||||
# 295| r295_2(glval<unknown>) = FunctionAddress[operator new] :
|
||||
# 295| r295_3(unsigned long) = Constant[4] :
|
||||
# 295| r295_4(void *) = Call[operator new] : func:r295_2, 0:r295_3
|
||||
# 295| m295_5(unknown) = ^CallSideEffect : ~m294_14
|
||||
# 295| m295_6(unknown) = Chi : total:m294_14, partial:m295_5
|
||||
# 295| m295_5(unknown) = ^CallSideEffect : ~m294_27
|
||||
# 295| m295_6(unknown) = Chi : total:m294_27, partial:m295_5
|
||||
# 295| m295_7(unknown) = ^InitializeDynamicAllocation : &:r295_4
|
||||
# 295| r295_8(A *) = Convert : r295_4
|
||||
# 295| r295_9(glval<unknown>) = FunctionAddress[A] :
|
||||
# 295| v295_10(void) = Call[A] : func:r295_9, this:r295_8
|
||||
# 295| m295_11(A) = ^IndirectMayWriteSideEffect[-1] : &:r295_8
|
||||
# 295| m295_12(unknown) = Chi : total:m295_7, partial:m295_11
|
||||
# 295| m295_13(A *) = Store[a] : &:r295_1, r295_8
|
||||
# 295| m295_11(unknown) = ^CallSideEffect : ~m295_6
|
||||
# 295| m295_12(unknown) = Chi : total:m295_6, partial:m295_11
|
||||
# 295| m295_13(A) = ^IndirectMayWriteSideEffect[-1] : &:r295_8
|
||||
# 295| m295_14(unknown) = Chi : total:m295_7, partial:m295_13
|
||||
# 295| m295_15(A *) = Store[a] : &:r295_1, r295_8
|
||||
# 296| r296_1(glval<Point *>) = VariableAddress[#return] :
|
||||
# 296| r296_2(glval<Point *>) = VariableAddress[p] :
|
||||
# 296| r296_3(Point *) = Load[p] : &:r296_2, m292_9
|
||||
# 296| m296_4(Point *) = Store[#return] : &:r296_1, r296_3
|
||||
# 291| r291_7(glval<Point *>) = VariableAddress[#return] :
|
||||
# 291| v291_8(void) = ReturnValue : &:r291_7, m296_4
|
||||
# 291| v291_9(void) = AliasedUse : ~m295_6
|
||||
# 291| v291_9(void) = AliasedUse : ~m295_12
|
||||
# 291| v291_10(void) = ExitFunction :
|
||||
|
||||
# 301| int main(int, char**)
|
||||
|
||||
@@ -1045,36 +1045,46 @@ ssa.cpp:
|
||||
# 240| r240_3(glval<unknown>) = FunctionAddress[Constructible] :
|
||||
# 240| r240_4(int) = Constant[1] :
|
||||
# 240| v240_5(void) = Call[Constructible] : func:r240_3, this:r240_1, 0:r240_4
|
||||
# 240| m240_6(Constructible) = ^IndirectMayWriteSideEffect[-1] : &:r240_1
|
||||
# 240| m240_7(Constructible) = Chi : total:m240_2, partial:m240_6
|
||||
# 240| m240_6(unknown) = ^CallSideEffect : ~m239_4
|
||||
# 240| m240_7(unknown) = Chi : total:m239_4, partial:m240_6
|
||||
# 240| m240_8(Constructible) = ^IndirectMayWriteSideEffect[-1] : &:r240_1
|
||||
# 240| m240_9(Constructible) = Chi : total:m240_2, partial:m240_8
|
||||
# 241| r241_1(glval<Constructible>) = VariableAddress[c] :
|
||||
# 241| r241_2(glval<unknown>) = FunctionAddress[g] :
|
||||
# 241| v241_3(void) = Call[g] : func:r241_2, this:r241_1
|
||||
# 241| v241_4(void) = ^IndirectReadSideEffect[-1] : &:r241_1, m240_7
|
||||
# 241| m241_5(Constructible) = ^IndirectMayWriteSideEffect[-1] : &:r241_1
|
||||
# 241| m241_6(Constructible) = Chi : total:m240_7, partial:m241_5
|
||||
# 241| m241_4(unknown) = ^CallSideEffect : ~m240_7
|
||||
# 241| m241_5(unknown) = Chi : total:m240_7, partial:m241_4
|
||||
# 241| v241_6(void) = ^IndirectReadSideEffect[-1] : &:r241_1, m240_9
|
||||
# 241| m241_7(Constructible) = ^IndirectMayWriteSideEffect[-1] : &:r241_1
|
||||
# 241| m241_8(Constructible) = Chi : total:m240_9, partial:m241_7
|
||||
# 242| r242_1(glval<Constructible>) = VariableAddress[c] :
|
||||
# 242| r242_2(glval<unknown>) = FunctionAddress[g] :
|
||||
# 242| v242_3(void) = Call[g] : func:r242_2, this:r242_1
|
||||
# 242| v242_4(void) = ^IndirectReadSideEffect[-1] : &:r242_1, m241_6
|
||||
# 242| m242_5(Constructible) = ^IndirectMayWriteSideEffect[-1] : &:r242_1
|
||||
# 242| m242_6(Constructible) = Chi : total:m241_6, partial:m242_5
|
||||
# 242| m242_4(unknown) = ^CallSideEffect : ~m241_5
|
||||
# 242| m242_5(unknown) = Chi : total:m241_5, partial:m242_4
|
||||
# 242| v242_6(void) = ^IndirectReadSideEffect[-1] : &:r242_1, m241_8
|
||||
# 242| m242_7(Constructible) = ^IndirectMayWriteSideEffect[-1] : &:r242_1
|
||||
# 242| m242_8(Constructible) = Chi : total:m241_8, partial:m242_7
|
||||
# 243| r243_1(glval<Constructible>) = VariableAddress[c2] :
|
||||
# 243| m243_2(Constructible) = Uninitialized[c2] : &:r243_1
|
||||
# 243| r243_3(glval<unknown>) = FunctionAddress[Constructible] :
|
||||
# 243| r243_4(int) = Constant[2] :
|
||||
# 243| v243_5(void) = Call[Constructible] : func:r243_3, this:r243_1, 0:r243_4
|
||||
# 243| m243_6(Constructible) = ^IndirectMayWriteSideEffect[-1] : &:r243_1
|
||||
# 243| m243_7(Constructible) = Chi : total:m243_2, partial:m243_6
|
||||
# 243| m243_6(unknown) = ^CallSideEffect : ~m242_5
|
||||
# 243| m243_7(unknown) = Chi : total:m242_5, partial:m243_6
|
||||
# 243| m243_8(Constructible) = ^IndirectMayWriteSideEffect[-1] : &:r243_1
|
||||
# 243| m243_9(Constructible) = Chi : total:m243_2, partial:m243_8
|
||||
# 244| r244_1(glval<Constructible>) = VariableAddress[c2] :
|
||||
# 244| r244_2(glval<unknown>) = FunctionAddress[g] :
|
||||
# 244| v244_3(void) = Call[g] : func:r244_2, this:r244_1
|
||||
# 244| v244_4(void) = ^IndirectReadSideEffect[-1] : &:r244_1, m243_7
|
||||
# 244| m244_5(Constructible) = ^IndirectMayWriteSideEffect[-1] : &:r244_1
|
||||
# 244| m244_6(Constructible) = Chi : total:m243_7, partial:m244_5
|
||||
# 244| m244_4(unknown) = ^CallSideEffect : ~m243_7
|
||||
# 244| m244_5(unknown) = Chi : total:m243_7, partial:m244_4
|
||||
# 244| v244_6(void) = ^IndirectReadSideEffect[-1] : &:r244_1, m243_9
|
||||
# 244| m244_7(Constructible) = ^IndirectMayWriteSideEffect[-1] : &:r244_1
|
||||
# 244| m244_8(Constructible) = Chi : total:m243_9, partial:m244_7
|
||||
# 245| v245_1(void) = NoOp :
|
||||
# 239| v239_5(void) = ReturnVoid :
|
||||
# 239| v239_6(void) = AliasedUse : m239_3
|
||||
# 239| v239_6(void) = AliasedUse : ~m244_5
|
||||
# 239| v239_7(void) = ExitFunction :
|
||||
|
||||
# 247| char* VoidStarIndirectParameters(char*, int)
|
||||
@@ -1375,37 +1385,43 @@ ssa.cpp:
|
||||
# 294| r294_18(glval<int>) = VariableAddress[x] :
|
||||
# 294| r294_19(int) = Load[x] : &:r294_18, m291_6
|
||||
# 294| v294_20(void) = Call[A] : func:r294_17, this:r294_16, 0:r294_19
|
||||
# 294| m294_21(A) = ^IndirectMayWriteSideEffect[-1] : &:r294_16
|
||||
# 294| m294_22(unknown) = Chi : total:m294_15, partial:m294_21
|
||||
# 294| v294_23(void) = Call[A] : func:r294_9, this:r294_8, 0:r294_16
|
||||
# 294| v294_24(void) = ^BufferReadSideEffect[0] : &:r294_16, ~m294_22
|
||||
# 294| m294_25(A) = ^IndirectMayWriteSideEffect[-1] : &:r294_8
|
||||
# 294| m294_26(unknown) = Chi : total:m294_7, partial:m294_25
|
||||
# 294| m294_27(unknown) = ^BufferMayWriteSideEffect[0] : &:r294_16
|
||||
# 294| m294_28(unknown) = Chi : total:m294_22, partial:m294_27
|
||||
# 294| r294_29(glval<int>) = FieldAddress[i] : r294_8
|
||||
# 294| r294_30(int) = Load[?] : &:r294_29, ~m294_26
|
||||
# 294| m294_31(int) = Store[j] : &:r294_1, r294_30
|
||||
# 294| m294_21(unknown) = ^CallSideEffect : ~m294_14
|
||||
# 294| m294_22(unknown) = Chi : total:m294_14, partial:m294_21
|
||||
# 294| m294_23(A) = ^IndirectMayWriteSideEffect[-1] : &:r294_16
|
||||
# 294| m294_24(unknown) = Chi : total:m294_15, partial:m294_23
|
||||
# 294| v294_25(void) = Call[A] : func:r294_9, this:r294_8, 0:r294_16
|
||||
# 294| m294_26(unknown) = ^CallSideEffect : ~m294_22
|
||||
# 294| m294_27(unknown) = Chi : total:m294_22, partial:m294_26
|
||||
# 294| v294_28(void) = ^BufferReadSideEffect[0] : &:r294_16, ~m294_24
|
||||
# 294| m294_29(A) = ^IndirectMayWriteSideEffect[-1] : &:r294_8
|
||||
# 294| m294_30(unknown) = Chi : total:m294_7, partial:m294_29
|
||||
# 294| m294_31(unknown) = ^BufferMayWriteSideEffect[0] : &:r294_16
|
||||
# 294| m294_32(unknown) = Chi : total:m294_24, partial:m294_31
|
||||
# 294| r294_33(glval<int>) = FieldAddress[i] : r294_8
|
||||
# 294| r294_34(int) = Load[?] : &:r294_33, ~m294_30
|
||||
# 294| m294_35(int) = Store[j] : &:r294_1, r294_34
|
||||
# 295| r295_1(glval<A *>) = VariableAddress[a] :
|
||||
# 295| r295_2(glval<unknown>) = FunctionAddress[operator new] :
|
||||
# 295| r295_3(unsigned long) = Constant[4] :
|
||||
# 295| r295_4(void *) = Call[operator new] : func:r295_2, 0:r295_3
|
||||
# 295| m295_5(unknown) = ^CallSideEffect : ~m294_14
|
||||
# 295| m295_6(unknown) = Chi : total:m294_14, partial:m295_5
|
||||
# 295| m295_5(unknown) = ^CallSideEffect : ~m294_27
|
||||
# 295| m295_6(unknown) = Chi : total:m294_27, partial:m295_5
|
||||
# 295| m295_7(unknown) = ^InitializeDynamicAllocation : &:r295_4
|
||||
# 295| r295_8(A *) = Convert : r295_4
|
||||
# 295| r295_9(glval<unknown>) = FunctionAddress[A] :
|
||||
# 295| v295_10(void) = Call[A] : func:r295_9, this:r295_8
|
||||
# 295| m295_11(A) = ^IndirectMayWriteSideEffect[-1] : &:r295_8
|
||||
# 295| m295_12(unknown) = Chi : total:m295_7, partial:m295_11
|
||||
# 295| m295_13(A *) = Store[a] : &:r295_1, r295_8
|
||||
# 295| m295_11(unknown) = ^CallSideEffect : ~m295_6
|
||||
# 295| m295_12(unknown) = Chi : total:m295_6, partial:m295_11
|
||||
# 295| m295_13(A) = ^IndirectMayWriteSideEffect[-1] : &:r295_8
|
||||
# 295| m295_14(unknown) = Chi : total:m295_7, partial:m295_13
|
||||
# 295| m295_15(A *) = Store[a] : &:r295_1, r295_8
|
||||
# 296| r296_1(glval<Point *>) = VariableAddress[#return] :
|
||||
# 296| r296_2(glval<Point *>) = VariableAddress[p] :
|
||||
# 296| r296_3(Point *) = Load[p] : &:r296_2, m292_9
|
||||
# 296| m296_4(Point *) = Store[#return] : &:r296_1, r296_3
|
||||
# 291| r291_7(glval<Point *>) = VariableAddress[#return] :
|
||||
# 291| v291_8(void) = ReturnValue : &:r291_7, m296_4
|
||||
# 291| v291_9(void) = AliasedUse : ~m295_6
|
||||
# 291| v291_9(void) = AliasedUse : ~m295_12
|
||||
# 291| v291_10(void) = ExitFunction :
|
||||
|
||||
# 301| int main(int, char**)
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import cpp
|
||||
|
||||
from Class c, boolean ispod
|
||||
where if c.isPOD() then ispod = true else ispod = false
|
||||
where if c.isPod() then ispod = true else ispod = false
|
||||
select c, ispod
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import semmle.code.cpp.PODType03
|
||||
|
||||
from Class c, boolean ispod
|
||||
where if isPODClass03(c) then ispod = true else ispod = false
|
||||
where if isPodClass03(c) then ispod = true else ispod = false
|
||||
select c, ispod
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import Microsoft.SAL
|
||||
|
||||
from SALAnnotation a
|
||||
from SalAnnotation a
|
||||
select a, a.getDeclaration()
|
||||
|
||||
@@ -149,6 +149,9 @@ uniqueNodeLocation
|
||||
| conditional_destructors.cpp:29:6:29:7 | EnterFunction | Node should have one location but has 2. |
|
||||
| conditional_destructors.cpp:29:6:29:7 | ExitFunction | Node should have one location but has 2. |
|
||||
| conditional_destructors.cpp:29:6:29:7 | InitializeNonLocal | Node should have one location but has 2. |
|
||||
| conditional_destructors.cpp:29:6:29:7 | Phi | Node should have one location but has 2. |
|
||||
| conditional_destructors.cpp:29:6:29:7 | Phi | Node should have one location but has 2. |
|
||||
| conditional_destructors.cpp:29:6:29:7 | Phi | Node should have one location but has 2. |
|
||||
| conditional_destructors.cpp:29:6:29:7 | ReturnVoid | Node should have one location but has 2. |
|
||||
| conditional_destructors.cpp:29:6:29:7 | SideEffect | Node should have one location but has 2. |
|
||||
| conditional_destructors.cpp:38:6:38:7 | AliasedDefinition | Node should have one location but has 2. |
|
||||
@@ -159,6 +162,9 @@ uniqueNodeLocation
|
||||
| conditional_destructors.cpp:38:6:38:7 | EnterFunction | Node should have one location but has 2. |
|
||||
| conditional_destructors.cpp:38:6:38:7 | ExitFunction | Node should have one location but has 2. |
|
||||
| conditional_destructors.cpp:38:6:38:7 | InitializeNonLocal | Node should have one location but has 2. |
|
||||
| conditional_destructors.cpp:38:6:38:7 | Phi | Node should have one location but has 2. |
|
||||
| conditional_destructors.cpp:38:6:38:7 | Phi | Node should have one location but has 2. |
|
||||
| conditional_destructors.cpp:38:6:38:7 | Phi | Node should have one location but has 2. |
|
||||
| conditional_destructors.cpp:38:6:38:7 | ReturnVoid | Node should have one location but has 2. |
|
||||
| conditional_destructors.cpp:38:6:38:7 | SideEffect | Node should have one location but has 2. |
|
||||
| conditional_destructors.cpp:38:6:38:7 | Unreached | Node should have one location but has 2. |
|
||||
@@ -555,6 +561,9 @@ uniqueNodeLocation
|
||||
| forstmt.cpp:1:6:1:7 | EnterFunction | Node should have one location but has 2. |
|
||||
| forstmt.cpp:1:6:1:7 | ExitFunction | Node should have one location but has 2. |
|
||||
| forstmt.cpp:1:6:1:7 | InitializeNonLocal | Node should have one location but has 2. |
|
||||
| forstmt.cpp:1:6:1:7 | Phi | Node should have one location but has 2. |
|
||||
| forstmt.cpp:1:6:1:7 | Phi | Node should have one location but has 2. |
|
||||
| forstmt.cpp:1:6:1:7 | Phi | Node should have one location but has 2. |
|
||||
| forstmt.cpp:1:6:1:7 | ReturnVoid | Node should have one location but has 2. |
|
||||
| forstmt.cpp:1:6:1:7 | SideEffect | Node should have one location but has 2. |
|
||||
| forstmt.cpp:8:6:8:7 | AliasedDefinition | Node should have one location but has 2. |
|
||||
@@ -565,6 +574,9 @@ uniqueNodeLocation
|
||||
| forstmt.cpp:8:6:8:7 | EnterFunction | Node should have one location but has 2. |
|
||||
| forstmt.cpp:8:6:8:7 | ExitFunction | Node should have one location but has 2. |
|
||||
| forstmt.cpp:8:6:8:7 | InitializeNonLocal | Node should have one location but has 2. |
|
||||
| forstmt.cpp:8:6:8:7 | Phi | Node should have one location but has 2. |
|
||||
| forstmt.cpp:8:6:8:7 | Phi | Node should have one location but has 2. |
|
||||
| forstmt.cpp:8:6:8:7 | Phi | Node should have one location but has 2. |
|
||||
| forstmt.cpp:8:6:8:7 | ReturnVoid | Node should have one location but has 2. |
|
||||
| forstmt.cpp:8:6:8:7 | SideEffect | Node should have one location but has 2. |
|
||||
| forstmt.cpp:8:6:8:7 | Unreached | Node should have one location but has 2. |
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
| test.cpp:5:7:5:8 | p0 | 5:c7-c8 6:c7-c8 |
|
||||
| test.cpp:5:7:5:13 | ... + ... | 5:c7-c13 6:c7-c13 7:c7-c7 |
|
||||
| test.cpp:5:12:5:13 | p1 | 5:c12-c13 6:c12-c13 |
|
||||
| test.cpp:10:16:10:16 | 1 | 10:c16-c16 176:c7-c7 178:c7-c7 |
|
||||
| test.cpp:16:3:16:3 | x | 16:c3-c3 17:c3-c3 |
|
||||
| test.cpp:16:7:16:8 | p0 | 16:c7-c8 17:c7-c8 |
|
||||
| test.cpp:16:7:16:13 | ... + ... | 16:c7-c13 17:c7-c13 |
|
||||
@@ -39,9 +38,3 @@
|
||||
| test.cpp:145:15:145:15 | y | 145:c15-c15 147:c7-c7 |
|
||||
| test.cpp:153:11:153:18 | global_a | 153:c11-c18 154:c11-c18 156:c3-c10 |
|
||||
| test.cpp:153:21:153:21 | x | 153:c21-c21 154:c21-c21 |
|
||||
| test.cpp:166:18:166:20 | (const char *)... | 166:c18-c20 167:c18-c20 173:c18-c20 |
|
||||
| test.cpp:166:18:166:20 | dst | 166:c18-c20 167:c18-c20 171:c10-c12 173:c18-c20 |
|
||||
| test.cpp:168:18:168:20 | (const char *)... | 168:c18-c20 169:c18-c20 171:c15-c17 174:c18-c20 |
|
||||
| test.cpp:168:18:168:20 | src | 168:c18-c20 169:c18-c20 171:c15-c17 174:c18-c20 |
|
||||
| test.cpp:176:10:176:10 | 2 | 176:c10-c10 178:c10-c10 21:c16-c16 |
|
||||
| test.cpp:177:7:177:7 | 3 | 177:c7-c7 35:c16-c16 |
|
||||
|
||||
@@ -44,11 +44,3 @@
|
||||
| test.cpp:144:15:144:15 | GVN | 144:c15-c15 149:c15-c15 |
|
||||
| test.cpp:153:11:153:18 | GVN | 153:c11-c18 154:c11-c18 156:c3-c10 |
|
||||
| test.cpp:153:21:153:21 | GVN | 153:c21-c21 154:c21-c21 |
|
||||
| test.cpp:166:11:166:16 | GVN | 166:c11-c16 167:c11-c16 |
|
||||
| test.cpp:166:18:166:20 | GVN | 166:c18-c20 167:c18-c20 171:c10-c12 173:c18-c20 |
|
||||
| test.cpp:166:18:166:20 | GVN | 166:c18-c20 167:c18-c20 173:c18-c20 |
|
||||
| test.cpp:168:11:168:16 | GVN | 168:c11-c16 169:c11-c16 174:c11-c16 |
|
||||
| test.cpp:168:18:168:20 | GVN | 168:c18-c20 169:c18-c20 171:c15-c17 174:c18-c20 |
|
||||
| test.cpp:168:18:168:20 | GVN | 168:c18-c20 169:c18-c20 171:c15-c17 174:c18-c20 |
|
||||
| test.cpp:176:7:176:7 | GVN | 176:c7-c7 178:c7-c7 |
|
||||
| test.cpp:176:10:176:10 | GVN | 176:c10-c10 178:c10-c10 |
|
||||
|
||||
@@ -1,20 +1,15 @@
|
||||
| test.cpp:5:3:5:13 | ... = ... | test.cpp:5:3:5:13 | ... = ... | AST only |
|
||||
| test.cpp:6:3:6:13 | ... = ... | test.cpp:6:3:6:13 | ... = ... | AST only |
|
||||
| test.cpp:7:3:7:7 | ... = ... | test.cpp:7:3:7:7 | ... = ... | AST only |
|
||||
| test.cpp:10:16:10:16 | 1 | test.cpp:176:7:176:7 | 1 | AST only |
|
||||
| test.cpp:10:16:10:16 | 1 | test.cpp:178:7:178:7 | 1 | AST only |
|
||||
| test.cpp:16:3:16:24 | ... = ... | test.cpp:16:3:16:24 | ... = ... | AST only |
|
||||
| test.cpp:17:3:17:24 | ... = ... | test.cpp:17:3:17:24 | ... = ... | AST only |
|
||||
| test.cpp:18:3:18:7 | ... = ... | test.cpp:18:3:18:7 | ... = ... | AST only |
|
||||
| test.cpp:21:16:21:16 | 2 | test.cpp:176:10:176:10 | 2 | AST only |
|
||||
| test.cpp:21:16:21:16 | 2 | test.cpp:178:10:178:10 | 2 | AST only |
|
||||
| test.cpp:29:3:29:3 | x | test.cpp:31:3:31:3 | x | IR only |
|
||||
| test.cpp:29:3:29:24 | ... = ... | test.cpp:29:3:29:24 | ... = ... | AST only |
|
||||
| test.cpp:30:3:30:17 | call to change_global02 | test.cpp:30:3:30:17 | call to change_global02 | AST only |
|
||||
| test.cpp:31:3:31:3 | x | test.cpp:29:3:29:3 | x | IR only |
|
||||
| test.cpp:31:3:31:24 | ... = ... | test.cpp:31:3:31:24 | ... = ... | AST only |
|
||||
| test.cpp:32:3:32:7 | ... = ... | test.cpp:32:3:32:7 | ... = ... | AST only |
|
||||
| test.cpp:35:16:35:16 | 3 | test.cpp:177:7:177:7 | 3 | AST only |
|
||||
| test.cpp:43:3:43:3 | x | test.cpp:45:3:45:3 | x | IR only |
|
||||
| test.cpp:43:3:43:24 | ... = ... | test.cpp:43:3:43:24 | ... = ... | AST only |
|
||||
| test.cpp:43:7:43:24 | ... + ... | test.cpp:45:7:45:24 | ... + ... | IR only |
|
||||
@@ -132,41 +127,3 @@
|
||||
| test.cpp:147:7:147:7 | y | test.cpp:145:15:145:15 | y | AST only |
|
||||
| test.cpp:149:15:149:15 | x | test.cpp:144:15:144:15 | x | IR only |
|
||||
| test.cpp:156:3:156:17 | ... = ... | test.cpp:156:3:156:17 | ... = ... | AST only |
|
||||
| test.cpp:166:11:166:16 | call to strlen | test.cpp:167:11:167:16 | call to strlen | IR only |
|
||||
| test.cpp:166:18:166:20 | (const char *)... | test.cpp:166:18:166:20 | (const char *)... | AST only |
|
||||
| test.cpp:166:18:166:20 | (const char *)... | test.cpp:167:18:167:20 | (const char *)... | AST only |
|
||||
| test.cpp:166:18:166:20 | (const char *)... | test.cpp:173:18:173:20 | (const char *)... | AST only |
|
||||
| test.cpp:167:11:167:16 | call to strlen | test.cpp:166:11:166:16 | call to strlen | IR only |
|
||||
| test.cpp:167:18:167:20 | (const char *)... | test.cpp:166:18:166:20 | (const char *)... | AST only |
|
||||
| test.cpp:167:18:167:20 | (const char *)... | test.cpp:167:18:167:20 | (const char *)... | AST only |
|
||||
| test.cpp:167:18:167:20 | (const char *)... | test.cpp:173:18:173:20 | (const char *)... | AST only |
|
||||
| test.cpp:168:11:168:16 | call to strlen | test.cpp:169:11:169:16 | call to strlen | IR only |
|
||||
| test.cpp:168:11:168:16 | call to strlen | test.cpp:174:11:174:16 | call to strlen | IR only |
|
||||
| test.cpp:168:18:168:20 | (const char *)... | test.cpp:168:18:168:20 | (const char *)... | AST only |
|
||||
| test.cpp:168:18:168:20 | (const char *)... | test.cpp:169:18:169:20 | (const char *)... | AST only |
|
||||
| test.cpp:168:18:168:20 | (const char *)... | test.cpp:171:15:171:17 | (const char *)... | AST only |
|
||||
| test.cpp:168:18:168:20 | (const char *)... | test.cpp:174:18:174:20 | (const char *)... | AST only |
|
||||
| test.cpp:169:11:169:16 | call to strlen | test.cpp:168:11:168:16 | call to strlen | IR only |
|
||||
| test.cpp:169:11:169:16 | call to strlen | test.cpp:174:11:174:16 | call to strlen | IR only |
|
||||
| test.cpp:169:18:169:20 | (const char *)... | test.cpp:168:18:168:20 | (const char *)... | AST only |
|
||||
| test.cpp:169:18:169:20 | (const char *)... | test.cpp:169:18:169:20 | (const char *)... | AST only |
|
||||
| test.cpp:169:18:169:20 | (const char *)... | test.cpp:171:15:171:17 | (const char *)... | AST only |
|
||||
| test.cpp:169:18:169:20 | (const char *)... | test.cpp:174:18:174:20 | (const char *)... | AST only |
|
||||
| test.cpp:171:15:171:17 | (const char *)... | test.cpp:168:18:168:20 | (const char *)... | AST only |
|
||||
| test.cpp:171:15:171:17 | (const char *)... | test.cpp:169:18:169:20 | (const char *)... | AST only |
|
||||
| test.cpp:171:15:171:17 | (const char *)... | test.cpp:171:15:171:17 | (const char *)... | AST only |
|
||||
| test.cpp:171:15:171:17 | (const char *)... | test.cpp:174:18:174:20 | (const char *)... | AST only |
|
||||
| test.cpp:173:18:173:20 | (const char *)... | test.cpp:166:18:166:20 | (const char *)... | AST only |
|
||||
| test.cpp:173:18:173:20 | (const char *)... | test.cpp:167:18:167:20 | (const char *)... | AST only |
|
||||
| test.cpp:173:18:173:20 | (const char *)... | test.cpp:173:18:173:20 | (const char *)... | AST only |
|
||||
| test.cpp:174:11:174:16 | call to strlen | test.cpp:168:11:168:16 | call to strlen | IR only |
|
||||
| test.cpp:174:11:174:16 | call to strlen | test.cpp:169:11:169:16 | call to strlen | IR only |
|
||||
| test.cpp:174:18:174:20 | (const char *)... | test.cpp:168:18:168:20 | (const char *)... | AST only |
|
||||
| test.cpp:174:18:174:20 | (const char *)... | test.cpp:169:18:169:20 | (const char *)... | AST only |
|
||||
| test.cpp:174:18:174:20 | (const char *)... | test.cpp:171:15:171:17 | (const char *)... | AST only |
|
||||
| test.cpp:174:18:174:20 | (const char *)... | test.cpp:174:18:174:20 | (const char *)... | AST only |
|
||||
| test.cpp:176:7:176:7 | 1 | test.cpp:10:16:10:16 | 1 | AST only |
|
||||
| test.cpp:176:10:176:10 | 2 | test.cpp:21:16:21:16 | 2 | AST only |
|
||||
| test.cpp:177:7:177:7 | 3 | test.cpp:35:16:35:16 | 3 | AST only |
|
||||
| test.cpp:178:7:178:7 | 1 | test.cpp:10:16:10:16 | 1 | AST only |
|
||||
| test.cpp:178:10:178:10 | 2 | test.cpp:21:16:21:16 | 2 | AST only |
|
||||
|
||||
@@ -1145,206 +1145,3 @@ test.cpp:
|
||||
# 152| v152_7(void) = ReturnVoid :
|
||||
# 152| v152_8(void) = AliasedUse : ~m156_7
|
||||
# 152| v152_9(void) = ExitFunction :
|
||||
|
||||
# 163| int add(int, int)
|
||||
# 163| Block 0
|
||||
# 163| v163_1(void) = EnterFunction :
|
||||
# 163| m163_2(unknown) = AliasedDefinition :
|
||||
# 163| valnum = unique
|
||||
# 163| m163_3(unknown) = InitializeNonLocal :
|
||||
# 163| valnum = unique
|
||||
# 163| m163_4(unknown) = Chi : total:m163_2, partial:m163_3
|
||||
# 163| valnum = unique
|
||||
# 163| r163_5(glval<int>) = VariableAddress[a] :
|
||||
# 163| valnum = r163_10, r163_5
|
||||
# 163| m163_6(int) = InitializeParameter[a] : &:r163_5
|
||||
# 163| valnum = m163_6, r163_11
|
||||
# 163| r163_7(glval<int>) = VariableAddress[b] :
|
||||
# 163| valnum = r163_12, r163_7
|
||||
# 163| m163_8(int) = InitializeParameter[b] : &:r163_7
|
||||
# 163| valnum = m163_8, r163_13
|
||||
# 163| r163_9(glval<int>) = VariableAddress[#return] :
|
||||
# 163| valnum = r163_16, r163_9
|
||||
# 163| r163_10(glval<int>) = VariableAddress[a] :
|
||||
# 163| valnum = r163_10, r163_5
|
||||
# 163| r163_11(int) = Load[a] : &:r163_10, m163_6
|
||||
# 163| valnum = m163_6, r163_11
|
||||
# 163| r163_12(glval<int>) = VariableAddress[b] :
|
||||
# 163| valnum = r163_12, r163_7
|
||||
# 163| r163_13(int) = Load[b] : &:r163_12, m163_8
|
||||
# 163| valnum = m163_8, r163_13
|
||||
# 163| r163_14(int) = Add : r163_11, r163_13
|
||||
# 163| valnum = m163_15, r163_14
|
||||
# 163| m163_15(int) = Store[#return] : &:r163_9, r163_14
|
||||
# 163| valnum = m163_15, r163_14
|
||||
# 163| r163_16(glval<int>) = VariableAddress[#return] :
|
||||
# 163| valnum = r163_16, r163_9
|
||||
# 163| v163_17(void) = ReturnValue : &:r163_16, m163_15
|
||||
# 163| v163_18(void) = AliasedUse : m163_3
|
||||
# 163| v163_19(void) = ExitFunction :
|
||||
|
||||
# 165| void test_func_value_numbering(char*, char*)
|
||||
# 165| Block 0
|
||||
# 165| v165_1(void) = EnterFunction :
|
||||
# 165| m165_2(unknown) = AliasedDefinition :
|
||||
# 165| valnum = unique
|
||||
# 165| m165_3(unknown) = InitializeNonLocal :
|
||||
# 165| valnum = unique
|
||||
# 165| m165_4(unknown) = Chi : total:m165_2, partial:m165_3
|
||||
# 165| valnum = unique
|
||||
# 165| r165_5(glval<char *>) = VariableAddress[dst] :
|
||||
# 165| valnum = r165_5, r166_3, r167_3, r171_2, r173_3
|
||||
# 165| m165_6(char *) = InitializeParameter[dst] : &:r165_5
|
||||
# 165| valnum = m165_6, r165_7, r166_4, r167_4, r171_3, r173_4
|
||||
# 165| r165_7(char *) = Load[dst] : &:r165_5, m165_6
|
||||
# 165| valnum = m165_6, r165_7, r166_4, r167_4, r171_3, r173_4
|
||||
# 165| m165_8(unknown) = InitializeIndirection[dst] : &:r165_7
|
||||
# 165| valnum = unique
|
||||
# 165| r165_9(glval<char *>) = VariableAddress[src] :
|
||||
# 165| valnum = r165_9, r168_3, r169_3, r171_4, r174_3
|
||||
# 165| m165_10(char *) = InitializeParameter[src] : &:r165_9
|
||||
# 165| valnum = m165_10, r165_11, r168_4, r169_4, r171_5, r174_4
|
||||
# 165| r165_11(char *) = Load[src] : &:r165_9, m165_10
|
||||
# 165| valnum = m165_10, r165_11, r168_4, r169_4, r171_5, r174_4
|
||||
# 165| m165_12(unknown) = InitializeIndirection[src] : &:r165_11
|
||||
# 165| valnum = unique
|
||||
# 166| r166_1(glval<int>) = VariableAddress[a] :
|
||||
# 166| valnum = unique
|
||||
# 166| r166_2(glval<unknown>) = FunctionAddress[strlen] :
|
||||
# 166| valnum = unique
|
||||
# 166| r166_3(glval<char *>) = VariableAddress[dst] :
|
||||
# 166| valnum = r165_5, r166_3, r167_3, r171_2, r173_3
|
||||
# 166| r166_4(char *) = Load[dst] : &:r166_3, m165_6
|
||||
# 166| valnum = m165_6, r165_7, r166_4, r167_4, r171_3, r173_4
|
||||
# 166| r166_5(char *) = Convert : r166_4
|
||||
# 166| valnum = r166_5, r167_5, r173_5
|
||||
# 166| r166_6(int) = Call[strlen] : func:r166_2, 0:r166_5
|
||||
# 166| valnum = m166_8, m167_8, r166_6, r167_6
|
||||
# 166| v166_7(void) = ^BufferReadSideEffect[0] : &:r166_5, ~m165_8
|
||||
# 166| m166_8(int) = Store[a] : &:r166_1, r166_6
|
||||
# 166| valnum = m166_8, m167_8, r166_6, r167_6
|
||||
# 167| r167_1(glval<int>) = VariableAddress[b] :
|
||||
# 167| valnum = unique
|
||||
# 167| r167_2(glval<unknown>) = FunctionAddress[strlen] :
|
||||
# 167| valnum = unique
|
||||
# 167| r167_3(glval<char *>) = VariableAddress[dst] :
|
||||
# 167| valnum = r165_5, r166_3, r167_3, r171_2, r173_3
|
||||
# 167| r167_4(char *) = Load[dst] : &:r167_3, m165_6
|
||||
# 167| valnum = m165_6, r165_7, r166_4, r167_4, r171_3, r173_4
|
||||
# 167| r167_5(char *) = Convert : r167_4
|
||||
# 167| valnum = r166_5, r167_5, r173_5
|
||||
# 167| r167_6(int) = Call[strlen] : func:r167_2, 0:r167_5
|
||||
# 167| valnum = m166_8, m167_8, r166_6, r167_6
|
||||
# 167| v167_7(void) = ^BufferReadSideEffect[0] : &:r167_5, ~m165_8
|
||||
# 167| m167_8(int) = Store[b] : &:r167_1, r167_6
|
||||
# 167| valnum = m166_8, m167_8, r166_6, r167_6
|
||||
# 168| r168_1(glval<int>) = VariableAddress[c] :
|
||||
# 168| valnum = unique
|
||||
# 168| r168_2(glval<unknown>) = FunctionAddress[strlen] :
|
||||
# 168| valnum = unique
|
||||
# 168| r168_3(glval<char *>) = VariableAddress[src] :
|
||||
# 168| valnum = r165_9, r168_3, r169_3, r171_4, r174_3
|
||||
# 168| r168_4(char *) = Load[src] : &:r168_3, m165_10
|
||||
# 168| valnum = m165_10, r165_11, r168_4, r169_4, r171_5, r174_4
|
||||
# 168| r168_5(char *) = Convert : r168_4
|
||||
# 168| valnum = r168_5, r169_5, r171_6, r174_5
|
||||
# 168| r168_6(int) = Call[strlen] : func:r168_2, 0:r168_5
|
||||
# 168| valnum = m168_8, m169_8, m174_8, r168_6, r169_6, r174_6
|
||||
# 168| v168_7(void) = ^BufferReadSideEffect[0] : &:r168_5, ~m165_12
|
||||
# 168| m168_8(int) = Store[c] : &:r168_1, r168_6
|
||||
# 168| valnum = m168_8, m169_8, m174_8, r168_6, r169_6, r174_6
|
||||
# 169| r169_1(glval<int>) = VariableAddress[d] :
|
||||
# 169| valnum = unique
|
||||
# 169| r169_2(glval<unknown>) = FunctionAddress[strlen] :
|
||||
# 169| valnum = unique
|
||||
# 169| r169_3(glval<char *>) = VariableAddress[src] :
|
||||
# 169| valnum = r165_9, r168_3, r169_3, r171_4, r174_3
|
||||
# 169| r169_4(char *) = Load[src] : &:r169_3, m165_10
|
||||
# 169| valnum = m165_10, r165_11, r168_4, r169_4, r171_5, r174_4
|
||||
# 169| r169_5(char *) = Convert : r169_4
|
||||
# 169| valnum = r168_5, r169_5, r171_6, r174_5
|
||||
# 169| r169_6(int) = Call[strlen] : func:r169_2, 0:r169_5
|
||||
# 169| valnum = m168_8, m169_8, m174_8, r168_6, r169_6, r174_6
|
||||
# 169| v169_7(void) = ^BufferReadSideEffect[0] : &:r169_5, ~m165_12
|
||||
# 169| m169_8(int) = Store[d] : &:r169_1, r169_6
|
||||
# 169| valnum = m168_8, m169_8, m174_8, r168_6, r169_6, r174_6
|
||||
# 171| r171_1(glval<unknown>) = FunctionAddress[strcat] :
|
||||
# 171| valnum = unique
|
||||
# 171| r171_2(glval<char *>) = VariableAddress[dst] :
|
||||
# 171| valnum = r165_5, r166_3, r167_3, r171_2, r173_3
|
||||
# 171| r171_3(char *) = Load[dst] : &:r171_2, m165_6
|
||||
# 171| valnum = m165_6, r165_7, r166_4, r167_4, r171_3, r173_4
|
||||
# 171| r171_4(glval<char *>) = VariableAddress[src] :
|
||||
# 171| valnum = r165_9, r168_3, r169_3, r171_4, r174_3
|
||||
# 171| r171_5(char *) = Load[src] : &:r171_4, m165_10
|
||||
# 171| valnum = m165_10, r165_11, r168_4, r169_4, r171_5, r174_4
|
||||
# 171| r171_6(char *) = Convert : r171_5
|
||||
# 171| valnum = r168_5, r169_5, r171_6, r174_5
|
||||
# 171| r171_7(char *) = Call[strcat] : func:r171_1, 0:r171_3, 1:r171_6
|
||||
# 171| valnum = unique
|
||||
# 171| v171_8(void) = ^BufferReadSideEffect[0] : &:r171_3, ~m165_8
|
||||
# 171| v171_9(void) = ^BufferReadSideEffect[1] : &:r171_6, ~m165_12
|
||||
# 171| m171_10(unknown) = ^BufferMayWriteSideEffect[0] : &:r171_3
|
||||
# 171| valnum = unique
|
||||
# 171| m171_11(unknown) = Chi : total:m165_8, partial:m171_10
|
||||
# 171| valnum = unique
|
||||
# 173| r173_1(glval<int>) = VariableAddress[e] :
|
||||
# 173| valnum = unique
|
||||
# 173| r173_2(glval<unknown>) = FunctionAddress[strlen] :
|
||||
# 173| valnum = unique
|
||||
# 173| r173_3(glval<char *>) = VariableAddress[dst] :
|
||||
# 173| valnum = r165_5, r166_3, r167_3, r171_2, r173_3
|
||||
# 173| r173_4(char *) = Load[dst] : &:r173_3, m165_6
|
||||
# 173| valnum = m165_6, r165_7, r166_4, r167_4, r171_3, r173_4
|
||||
# 173| r173_5(char *) = Convert : r173_4
|
||||
# 173| valnum = r166_5, r167_5, r173_5
|
||||
# 173| r173_6(int) = Call[strlen] : func:r173_2, 0:r173_5
|
||||
# 173| valnum = m173_8, r173_6
|
||||
# 173| v173_7(void) = ^BufferReadSideEffect[0] : &:r173_5, ~m171_11
|
||||
# 173| m173_8(int) = Store[e] : &:r173_1, r173_6
|
||||
# 173| valnum = m173_8, r173_6
|
||||
# 174| r174_1(glval<int>) = VariableAddress[f] :
|
||||
# 174| valnum = unique
|
||||
# 174| r174_2(glval<unknown>) = FunctionAddress[strlen] :
|
||||
# 174| valnum = unique
|
||||
# 174| r174_3(glval<char *>) = VariableAddress[src] :
|
||||
# 174| valnum = r165_9, r168_3, r169_3, r171_4, r174_3
|
||||
# 174| r174_4(char *) = Load[src] : &:r174_3, m165_10
|
||||
# 174| valnum = m165_10, r165_11, r168_4, r169_4, r171_5, r174_4
|
||||
# 174| r174_5(char *) = Convert : r174_4
|
||||
# 174| valnum = r168_5, r169_5, r171_6, r174_5
|
||||
# 174| r174_6(int) = Call[strlen] : func:r174_2, 0:r174_5
|
||||
# 174| valnum = m168_8, m169_8, m174_8, r168_6, r169_6, r174_6
|
||||
# 174| v174_7(void) = ^BufferReadSideEffect[0] : &:r174_5, ~m165_12
|
||||
# 174| m174_8(int) = Store[f] : &:r174_1, r174_6
|
||||
# 174| valnum = m168_8, m169_8, m174_8, r168_6, r169_6, r174_6
|
||||
# 176| r176_1(glval<unknown>) = FunctionAddress[add] :
|
||||
# 176| valnum = unique
|
||||
# 176| r176_2(int) = Constant[1] :
|
||||
# 176| valnum = r176_2, r178_2
|
||||
# 176| r176_3(int) = Constant[2] :
|
||||
# 176| valnum = r176_3, r178_3
|
||||
# 176| r176_4(int) = Call[add] : func:r176_1, 0:r176_2, 1:r176_3
|
||||
# 176| valnum = unique
|
||||
# 177| r177_1(glval<unknown>) = FunctionAddress[add] :
|
||||
# 177| valnum = unique
|
||||
# 177| r177_2(int) = Constant[3] :
|
||||
# 177| valnum = unique
|
||||
# 177| r177_3(int) = Constant[4] :
|
||||
# 177| valnum = unique
|
||||
# 177| r177_4(int) = Call[add] : func:r177_1, 0:r177_2, 1:r177_3
|
||||
# 177| valnum = unique
|
||||
# 178| r178_1(glval<unknown>) = FunctionAddress[add] :
|
||||
# 178| valnum = unique
|
||||
# 178| r178_2(int) = Constant[1] :
|
||||
# 178| valnum = r176_2, r178_2
|
||||
# 178| r178_3(int) = Constant[2] :
|
||||
# 178| valnum = r176_3, r178_3
|
||||
# 178| r178_4(int) = Call[add] : func:r178_1, 0:r178_2, 1:r178_3
|
||||
# 178| valnum = unique
|
||||
# 179| v179_1(void) = NoOp :
|
||||
# 165| v165_13(void) = ReturnIndirection[dst] : &:r165_7, m171_11
|
||||
# 165| v165_14(void) = ReturnIndirection[src] : &:r165_11, m165_12
|
||||
# 165| v165_15(void) = ReturnVoid :
|
||||
# 165| v165_16(void) = AliasedUse : m165_3
|
||||
# 165| v165_17(void) = ExitFunction :
|
||||
|
||||
@@ -156,24 +156,4 @@ void test_read_global_different(int n) {
|
||||
global_a->y = n;
|
||||
|
||||
int d = global_a->x;
|
||||
}
|
||||
|
||||
int strlen(const char *str);
|
||||
char *strcat(char *dst, const char *src);
|
||||
int add(int a, int b) { return a+b; }
|
||||
|
||||
void test_func_value_numbering(char *dst, char *src) {
|
||||
int a = strlen(dst);
|
||||
int b = strlen(dst); // same as previous line
|
||||
int c = strlen(src);
|
||||
int d = strlen(src); // same as previous line
|
||||
|
||||
strcat(dst, src);
|
||||
|
||||
int e = strlen(dst); // different from a and b
|
||||
int f = strlen(src); // same as c and d
|
||||
|
||||
add(1, 2);
|
||||
add(3, 4);
|
||||
add(1, 2); // same as two lines earlier
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
| test.cpp:30:7:30:7 | i | $@ is read here, but may not have been written. It should be guarded by a check that the $@ returns at least 1. | test.cpp:30:7:30:7 | i | i | test.cpp:29:3:29:7 | call to scanf | call to scanf |
|
||||
| test.cpp:46:7:46:7 | i | $@ is read here, but may not have been written. It should be guarded by a check that the $@ returns at least 1. | test.cpp:46:7:46:7 | i | i | test.cpp:45:3:45:7 | call to scanf | call to scanf |
|
||||
| test.cpp:63:7:63:7 | i | $@ is read here, but may not have been written. It should be guarded by a check that the $@ returns at least 1. | test.cpp:63:7:63:7 | i | i | test.cpp:62:3:62:7 | call to scanf | call to scanf |
|
||||
| test.cpp:75:7:75:7 | i | $@ is read here, but may not have been written. It should be guarded by a check that the $@ returns at least 1. | test.cpp:75:7:75:7 | i | i | test.cpp:74:3:74:7 | call to scanf | call to scanf |
|
||||
| test.cpp:87:7:87:7 | i | $@ is read here, but may not have been written. It should be guarded by a check that the $@ returns at least 1. | test.cpp:87:7:87:7 | i | i | test.cpp:86:3:86:8 | call to fscanf | call to fscanf |
|
||||
| test.cpp:94:7:94:7 | i | $@ is read here, but may not have been written. It should be guarded by a check that the $@ returns at least 1. | test.cpp:94:7:94:7 | i | i | test.cpp:93:3:93:8 | call to sscanf | call to sscanf |
|
||||
| test.cpp:143:8:143:8 | i | $@ is read here, but may not have been written. It should be guarded by a check that the $@ returns at least 1. | test.cpp:143:8:143:8 | i | i | test.cpp:141:7:141:11 | call to scanf | call to scanf |
|
||||
| test.cpp:152:8:152:8 | i | $@ is read here, but may not have been written. It should be guarded by a check that the $@ returns at least 1. | test.cpp:152:8:152:8 | i | i | test.cpp:150:7:150:11 | call to scanf | call to scanf |
|
||||
| test.cpp:184:8:184:8 | i | $@ is read here, but may not have been written. It should be guarded by a check that the $@ returns at least 1. | test.cpp:184:8:184:8 | i | i | test.cpp:183:7:183:11 | call to scanf | call to scanf |
|
||||
| test.cpp:203:8:203:8 | j | $@ is read here, but may not have been written. It should be guarded by a check that the $@ returns at least 2. | test.cpp:203:8:203:8 | j | j | test.cpp:200:7:200:11 | call to scanf | call to scanf |
|
||||
| test.cpp:227:9:227:9 | d | $@ is read here, but may not have been written. It should be guarded by a check that the $@ returns at least 2. | test.cpp:227:9:227:9 | d | d | test.cpp:225:25:225:29 | call to scanf | call to scanf |
|
||||
| test.cpp:231:9:231:9 | d | $@ is read here, but may not have been written. It should be guarded by a check that the $@ returns at least 2. | test.cpp:231:9:231:9 | d | d | test.cpp:229:14:229:18 | call to scanf | call to scanf |
|
||||
| test.cpp:243:7:243:7 | i | $@ is read here, but may not have been written. It should be guarded by a check that the $@ returns at least 1. | test.cpp:243:7:243:7 | i | i | test.cpp:242:3:242:7 | call to scanf | call to scanf |
|
||||
| test.cpp:251:7:251:7 | i | $@ is read here, but may not have been written. It should be guarded by a check that the $@ returns at least 1. | test.cpp:251:7:251:7 | i | i | test.cpp:250:3:250:7 | call to scanf | call to scanf |
|
||||
| test.cpp:259:7:259:7 | i | $@ is read here, but may not have been written. It should be guarded by a check that the $@ returns at least 1. | test.cpp:259:7:259:7 | i | i | test.cpp:258:3:258:7 | call to scanf | call to scanf |
|
||||
| test.cpp:271:7:271:7 | i | $@ is read here, but may not have been written. It should be guarded by a check that the $@ returns at least 1. | test.cpp:271:7:271:7 | i | i | test.cpp:270:3:270:7 | call to scanf | call to scanf |
|
||||
| test.cpp:281:8:281:12 | ptr_i | $@ is read here, but may not have been written. It should be guarded by a check that the $@ returns at least 1. | test.cpp:281:8:281:12 | ptr_i | ptr_i | test.cpp:280:3:280:7 | call to scanf | call to scanf |
|
||||
| test.cpp:289:7:289:7 | i | $@ is read here, but may not have been written. It should be guarded by a check that the $@ returns at least 1. | test.cpp:289:7:289:7 | i | i | test.cpp:288:3:288:7 | call to scanf | call to scanf |
|
||||
| test.cpp:383:25:383:25 | u | $@ is read here, but may not have been written. It should be guarded by a check that the $@ returns at least 1. | test.cpp:383:25:383:25 | u | u | test.cpp:382:6:382:11 | call to sscanf | call to sscanf |
|
||||
@@ -0,0 +1 @@
|
||||
Critical/MissingCheckScanf.ql
|
||||
387
cpp/ql/test/query-tests/Critical/MissingCheckScanf/test.cpp
Normal file
387
cpp/ql/test/query-tests/Critical/MissingCheckScanf/test.cpp
Normal file
@@ -0,0 +1,387 @@
|
||||
typedef struct
|
||||
{
|
||||
} FILE;
|
||||
|
||||
typedef void *locale_t;
|
||||
|
||||
int scanf(const char *format, ...);
|
||||
int fscanf(FILE *stream, const char *format, ...);
|
||||
int sscanf(const char *s, const char *format, ...);
|
||||
int _scanf_l(const char *format, locale_t locale, ...);
|
||||
|
||||
void use(int i);
|
||||
|
||||
void set_by_ref(int &i);
|
||||
void set_by_ptr(int *i);
|
||||
bool maybe();
|
||||
|
||||
FILE *get_a_stream();
|
||||
const char *get_a_string();
|
||||
extern locale_t get_a_locale();
|
||||
|
||||
int main()
|
||||
{
|
||||
// --- simple cases ---
|
||||
|
||||
{
|
||||
int i;
|
||||
|
||||
scanf("%d", &i);
|
||||
use(i); // BAD: may not have written `i`
|
||||
}
|
||||
|
||||
{
|
||||
int i;
|
||||
|
||||
if (scanf("%d", &i) == 1)
|
||||
{
|
||||
use(i); // GOOD: checks return value
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
int i = 0;
|
||||
|
||||
scanf("%d", &i);
|
||||
use(i); // BAD. Design choice: already initialized variables shouldn't make a difference.
|
||||
}
|
||||
|
||||
{
|
||||
int i;
|
||||
use(i); // GOOD: only care about uses after scanf call
|
||||
|
||||
if (scanf("%d", &i) == 1)
|
||||
{
|
||||
use(i); // GOOD
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
int i; // Reused variable
|
||||
|
||||
scanf("%d", &i);
|
||||
use(i); // BAD
|
||||
|
||||
if (scanf("%d", &i) == 1)
|
||||
{
|
||||
use(i); // GOOD
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
int i; // Reset variable
|
||||
|
||||
scanf("%d", &i);
|
||||
use(i); // BAD
|
||||
|
||||
i = 1;
|
||||
use(i); // GOOD
|
||||
}
|
||||
|
||||
// --- different scanf functions ---
|
||||
|
||||
{
|
||||
int i;
|
||||
|
||||
fscanf(get_a_stream(), "%d", &i);
|
||||
use(i); // BAD: may not have written `i`
|
||||
}
|
||||
|
||||
{
|
||||
int i;
|
||||
|
||||
sscanf(get_a_string(), "%d", &i);
|
||||
use(i); // BAD: may not have written `i`
|
||||
}
|
||||
|
||||
{
|
||||
int i;
|
||||
|
||||
if (_scanf_l("%d", get_a_locale(), &i) == 1)
|
||||
{
|
||||
use(i); // GOOD
|
||||
}
|
||||
}
|
||||
|
||||
// --- different ways of checking ---
|
||||
|
||||
{
|
||||
int i;
|
||||
|
||||
if (scanf("%d", &i) >= 1)
|
||||
{
|
||||
use(i); // GOOD
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
int i;
|
||||
|
||||
if (scanf("%d", &i) == 1)
|
||||
{
|
||||
use(i); // GOOD
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
int i;
|
||||
|
||||
if (0 < scanf("%d", &i))
|
||||
{
|
||||
if (true)
|
||||
{
|
||||
use(i); // GOOD
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
int i;
|
||||
|
||||
if (scanf("%d", &i) != 0)
|
||||
{
|
||||
use(i); // BAD: scanf can return EOF
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
int i;
|
||||
|
||||
if (scanf("%d", &i) == 0)
|
||||
{
|
||||
use(i); // BAD: checks return value incorrectly
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
int r;
|
||||
int i;
|
||||
|
||||
r = scanf("%d", &i);
|
||||
|
||||
if (r >= 1)
|
||||
{
|
||||
use(i); // GOOD
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
bool b;
|
||||
int i;
|
||||
|
||||
b = scanf("%d", &i);
|
||||
|
||||
if (b >= 1)
|
||||
{
|
||||
use(i); // BAD [NOT DETECTED]: scanf can return EOF (boolifies true)
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
int i;
|
||||
|
||||
if (scanf("%d", &i))
|
||||
use(i); // BAD
|
||||
}
|
||||
|
||||
{
|
||||
int i, j;
|
||||
|
||||
if (scanf("%d %d", &i) >= 2)
|
||||
{
|
||||
use(i); // GOOD
|
||||
use(j); // GOOD: `j` is not a scanf arg, so out of scope of MissingCheckScanf
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
int i, j;
|
||||
|
||||
if (scanf("%d %d", &i, &j) >= 1)
|
||||
{
|
||||
use(i); // GOOD
|
||||
use(j); // BAD: checks return value incorrectly
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
int i, j;
|
||||
|
||||
if (scanf("%d %d", &i, &j) >= 2)
|
||||
{
|
||||
use(i); // GOOD
|
||||
use(j); // GOOD
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
char c[5];
|
||||
int d;
|
||||
|
||||
while(maybe()) {
|
||||
if (maybe()) {
|
||||
break;
|
||||
}
|
||||
else if (maybe() && (scanf("%5c %d", c, &d) == 1)) { // GOOD
|
||||
use(*(int *)c); // GOOD
|
||||
use(d); // BAD
|
||||
}
|
||||
else if ((scanf("%5c %d", c, &d) == 1) && maybe()) { // GOOD
|
||||
use(*(int *)c); // GOOD
|
||||
use(d); // BAD
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// --- different initialization ---
|
||||
|
||||
{
|
||||
int i;
|
||||
i = 0;
|
||||
|
||||
scanf("%d", &i);
|
||||
use(i); // BAD
|
||||
}
|
||||
|
||||
{
|
||||
int i;
|
||||
|
||||
set_by_ref(i);
|
||||
scanf("%d", &i);
|
||||
use(i); // BAD
|
||||
}
|
||||
|
||||
{
|
||||
int i;
|
||||
|
||||
set_by_ptr(&i);
|
||||
scanf("%d", &i);
|
||||
use(i); // BAD
|
||||
}
|
||||
|
||||
{
|
||||
int i;
|
||||
|
||||
if (maybe())
|
||||
{
|
||||
i = 0;
|
||||
}
|
||||
|
||||
scanf("%d", &i);
|
||||
use(i); // BAD: `i` may not have been initialized
|
||||
}
|
||||
|
||||
// --- different use ---
|
||||
|
||||
{
|
||||
int i;
|
||||
int *ptr_i = &i;
|
||||
|
||||
scanf("%d", &i);
|
||||
use(*ptr_i); // BAD: may not have written `i`
|
||||
}
|
||||
|
||||
{
|
||||
int i;
|
||||
int *ptr_i = &i;
|
||||
|
||||
scanf("%d", ptr_i);
|
||||
use(i); // BAD: may not have written `*ptr_i`
|
||||
}
|
||||
|
||||
{
|
||||
int i;
|
||||
scanf("%d", &i);
|
||||
i = 42;
|
||||
use(i); // GOOD
|
||||
}
|
||||
|
||||
// --- weird formatting strings ---
|
||||
|
||||
{
|
||||
int i, j;
|
||||
|
||||
if (sscanf("123", "%n %*d %n", &i, &j) >= 0)
|
||||
{
|
||||
use(i); // GOOD (`%n` does not consume input, but writes 0 to i)
|
||||
use(j); // GOOD (`%n` does not consume input, but writes 3 to j)
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
int i;
|
||||
|
||||
if (scanf("%% %d", &i) >= 1)
|
||||
{
|
||||
use(i); // GOOD (`%%` does not consume input)
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
int i;
|
||||
|
||||
if (scanf("%*d %d", &i) >= 1)
|
||||
{
|
||||
use(i); // GOOD (`%*d` does not consume input)
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
int d, n;
|
||||
|
||||
if (scanf("%*d %d %n", &d, &n) == 1) {
|
||||
use(d); // GOOD
|
||||
use(n); // GOOD
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
char substr[32];
|
||||
int n;
|
||||
while (sscanf(get_a_string(), "%31[^:]: %d", substr, &n) == 2) { // GOOD: cycle from write to unguarded access
|
||||
use(*(int *)substr); // GOOD
|
||||
use(n); // GOOD
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// --- Non-local cases ---
|
||||
|
||||
bool my_scan_int(int &i)
|
||||
{
|
||||
return scanf("%d", &i) == 1; // GOOD
|
||||
}
|
||||
|
||||
void my_scan_int_test()
|
||||
{
|
||||
int i;
|
||||
|
||||
use(i); // GOOD: used before scanf
|
||||
|
||||
my_scan_int(i);
|
||||
use(i); // BAD [NOT DETECTED]
|
||||
|
||||
if (my_scan_int(i))
|
||||
{
|
||||
use(i); // GOOD
|
||||
}
|
||||
}
|
||||
|
||||
// --- Can be OK'd given a sufficiently smart analysis ---
|
||||
|
||||
char *my_string_copy() {
|
||||
static const char SRC_STRING[] = "48656C6C6F";
|
||||
static char DST_STRING[] = ".....";
|
||||
|
||||
int len = sizeof(SRC_STRING) - 1;
|
||||
const char *src = SRC_STRING;
|
||||
char *ptr = DST_STRING;
|
||||
|
||||
for (int i = 0; i < len; i += 2) {
|
||||
unsigned int u;
|
||||
sscanf(src + i, "%2x", &u);
|
||||
*ptr++ = (char) u; // GOOD [FALSE POSITIVE]? src+i+{0,1} are always valid %x digits, so this should be OK.
|
||||
}
|
||||
*ptr++ = 0;
|
||||
return DST_STRING;
|
||||
}
|
||||
@@ -413,7 +413,7 @@ namespace Semmle.Autobuild.CSharp.Tests
|
||||
actions.RunProcess["cmd.exe /C dotnet --info"] = 0;
|
||||
actions.RunProcess[@"cmd.exe /C dotnet clean C:\Project\test.csproj"] = 0;
|
||||
actions.RunProcess[@"cmd.exe /C dotnet restore C:\Project\test.csproj"] = 0;
|
||||
actions.RunProcess[@"cmd.exe /C dotnet build --no-incremental /p:UseSharedCompilation=false C:\Project\test.csproj"] = 0;
|
||||
actions.RunProcess[@"cmd.exe /C dotnet build --no-incremental C:\Project\test.csproj"] = 0;
|
||||
actions.FileExists["csharp.log"] = true;
|
||||
actions.FileExists[@"C:\Project\test.csproj"] = true;
|
||||
actions.GetEnvironmentVariable["CODEQL_EXTRACTOR_CSHARP_TRAP_DIR"] = "";
|
||||
@@ -440,7 +440,7 @@ namespace Semmle.Autobuild.CSharp.Tests
|
||||
actions.RunProcess["dotnet --info"] = 0;
|
||||
actions.RunProcess[@"dotnet clean C:\Project/test.csproj"] = 0;
|
||||
actions.RunProcess[@"dotnet restore C:\Project/test.csproj"] = 0;
|
||||
actions.RunProcess[@"dotnet build --no-incremental /p:UseSharedCompilation=false C:\Project/test.csproj"] = 0;
|
||||
actions.RunProcess[@"dotnet build --no-incremental C:\Project/test.csproj"] = 0;
|
||||
actions.FileExists["csharp.log"] = true;
|
||||
actions.FileExists[@"C:\Project/test.csproj"] = true;
|
||||
actions.GetEnvironmentVariable["CODEQL_EXTRACTOR_CSHARP_TRAP_DIR"] = "";
|
||||
@@ -715,9 +715,9 @@ namespace Semmle.Autobuild.CSharp.Tests
|
||||
public void TestWindowCSharpMsBuild()
|
||||
{
|
||||
actions.RunProcess[@"cmd.exe /C C:\Project\.nuget\nuget.exe restore C:\Project\test1.sln -DisableParallelProcessing"] = 0;
|
||||
actions.RunProcess["cmd.exe /C CALL ^\"C:\\Program Files ^(x86^)\\Microsoft Visual Studio 12.0\\VC\\vcvarsall.bat^\" && set Platform=&& type NUL && msbuild C:\\Project\\test1.sln /p:UseSharedCompilation=false /t:Windows /p:Platform=\"x86\" /p:Configuration=\"Debug\" /p:MvcBuildViews=true /P:Fu=Bar"] = 0;
|
||||
actions.RunProcess["cmd.exe /C CALL ^\"C:\\Program Files ^(x86^)\\Microsoft Visual Studio 12.0\\VC\\vcvarsall.bat^\" && set Platform=&& type NUL && msbuild C:\\Project\\test1.sln /t:Windows /p:Platform=\"x86\" /p:Configuration=\"Debug\" /P:Fu=Bar"] = 0;
|
||||
actions.RunProcess[@"cmd.exe /C C:\Project\.nuget\nuget.exe restore C:\Project\test2.sln -DisableParallelProcessing"] = 0;
|
||||
actions.RunProcess["cmd.exe /C CALL ^\"C:\\Program Files ^(x86^)\\Microsoft Visual Studio 12.0\\VC\\vcvarsall.bat^\" && set Platform=&& type NUL && msbuild C:\\Project\\test2.sln /p:UseSharedCompilation=false /t:Windows /p:Platform=\"x86\" /p:Configuration=\"Debug\" /p:MvcBuildViews=true /P:Fu=Bar"] = 0;
|
||||
actions.RunProcess["cmd.exe /C CALL ^\"C:\\Program Files ^(x86^)\\Microsoft Visual Studio 12.0\\VC\\vcvarsall.bat^\" && set Platform=&& type NUL && msbuild C:\\Project\\test2.sln /t:Windows /p:Platform=\"x86\" /p:Configuration=\"Debug\" /P:Fu=Bar"] = 0;
|
||||
actions.FileExists["csharp.log"] = true;
|
||||
actions.FileExists[@"C:\Program Files (x86)\Microsoft Visual Studio\Installer\vswhere.exe"] = false;
|
||||
actions.FileExists[@"C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\vcvarsall.bat"] = false;
|
||||
@@ -746,9 +746,9 @@ namespace Semmle.Autobuild.CSharp.Tests
|
||||
public void TestWindowCSharpMsBuildMultipleSolutions()
|
||||
{
|
||||
actions.RunProcess[@"cmd.exe /C nuget restore C:\Project\test1.csproj -DisableParallelProcessing"] = 0;
|
||||
actions.RunProcess["cmd.exe /C CALL ^\"C:\\Program Files ^(x86^)\\Microsoft Visual Studio 12.0\\VC\\vcvarsall.bat^\" && set Platform=&& type NUL && msbuild C:\\Project\\test1.csproj /p:UseSharedCompilation=false /t:Windows /p:Platform=\"x86\" /p:Configuration=\"Debug\" /p:MvcBuildViews=true /P:Fu=Bar"] = 0;
|
||||
actions.RunProcess["cmd.exe /C CALL ^\"C:\\Program Files ^(x86^)\\Microsoft Visual Studio 12.0\\VC\\vcvarsall.bat^\" && set Platform=&& type NUL && msbuild C:\\Project\\test1.csproj /t:Windows /p:Platform=\"x86\" /p:Configuration=\"Debug\" /P:Fu=Bar"] = 0;
|
||||
actions.RunProcess[@"cmd.exe /C nuget restore C:\Project\test2.csproj -DisableParallelProcessing"] = 0;
|
||||
actions.RunProcess["cmd.exe /C CALL ^\"C:\\Program Files ^(x86^)\\Microsoft Visual Studio 12.0\\VC\\vcvarsall.bat^\" && set Platform=&& type NUL && msbuild C:\\Project\\test2.csproj /p:UseSharedCompilation=false /t:Windows /p:Platform=\"x86\" /p:Configuration=\"Debug\" /p:MvcBuildViews=true /P:Fu=Bar"] = 0;
|
||||
actions.RunProcess["cmd.exe /C CALL ^\"C:\\Program Files ^(x86^)\\Microsoft Visual Studio 12.0\\VC\\vcvarsall.bat^\" && set Platform=&& type NUL && msbuild C:\\Project\\test2.csproj /t:Windows /p:Platform=\"x86\" /p:Configuration=\"Debug\" /P:Fu=Bar"] = 0;
|
||||
actions.FileExists["csharp.log"] = true;
|
||||
actions.FileExists[@"C:\Project\test1.csproj"] = true;
|
||||
actions.FileExists[@"C:\Project\test2.csproj"] = true;
|
||||
@@ -791,7 +791,7 @@ namespace Semmle.Autobuild.CSharp.Tests
|
||||
public void TestWindowCSharpMsBuildFailed()
|
||||
{
|
||||
actions.RunProcess[@"cmd.exe /C nuget restore C:\Project\test1.sln -DisableParallelProcessing"] = 0;
|
||||
actions.RunProcess["cmd.exe /C CALL ^\"C:\\Program Files ^(x86^)\\Microsoft Visual Studio 12.0\\VC\\vcvarsall.bat^\" && set Platform=&& type NUL && msbuild C:\\Project\\test1.sln /p:UseSharedCompilation=false /t:Windows /p:Platform=\"x86\" /p:Configuration=\"Debug\" /p:MvcBuildViews=true /P:Fu=Bar"] = 1;
|
||||
actions.RunProcess["cmd.exe /C CALL ^\"C:\\Program Files ^(x86^)\\Microsoft Visual Studio 12.0\\VC\\vcvarsall.bat^\" && set Platform=&& type NUL && msbuild C:\\Project\\test1.sln /t:Windows /p:Platform=\"x86\" /p:Configuration=\"Debug\" /P:Fu=Bar"] = 1;
|
||||
actions.FileExists["csharp.log"] = true;
|
||||
actions.FileExists[@"C:\Program Files (x86)\Microsoft Visual Studio\Installer\vswhere.exe"] = false;
|
||||
actions.FileExists[@"C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\vcvarsall.bat"] = false;
|
||||
@@ -817,8 +817,8 @@ namespace Semmle.Autobuild.CSharp.Tests
|
||||
[Fact]
|
||||
public void TestSkipNugetMsBuild()
|
||||
{
|
||||
actions.RunProcess["cmd.exe /C CALL ^\"C:\\Program Files ^(x86^)\\Microsoft Visual Studio 12.0\\VC\\vcvarsall.bat^\" && set Platform=&& type NUL && msbuild C:\\Project\\test1.sln /p:UseSharedCompilation=false /t:Windows /p:Platform=\"x86\" /p:Configuration=\"Debug\" /p:MvcBuildViews=true /P:Fu=Bar"] = 0;
|
||||
actions.RunProcess["cmd.exe /C CALL ^\"C:\\Program Files ^(x86^)\\Microsoft Visual Studio 12.0\\VC\\vcvarsall.bat^\" && set Platform=&& type NUL && msbuild C:\\Project\\test2.sln /p:UseSharedCompilation=false /t:Windows /p:Platform=\"x86\" /p:Configuration=\"Debug\" /p:MvcBuildViews=true /P:Fu=Bar"] = 0;
|
||||
actions.RunProcess["cmd.exe /C CALL ^\"C:\\Program Files ^(x86^)\\Microsoft Visual Studio 12.0\\VC\\vcvarsall.bat^\" && set Platform=&& type NUL && msbuild C:\\Project\\test1.sln /t:Windows /p:Platform=\"x86\" /p:Configuration=\"Debug\" /P:Fu=Bar"] = 0;
|
||||
actions.RunProcess["cmd.exe /C CALL ^\"C:\\Program Files ^(x86^)\\Microsoft Visual Studio 12.0\\VC\\vcvarsall.bat^\" && set Platform=&& type NUL && msbuild C:\\Project\\test2.sln /t:Windows /p:Platform=\"x86\" /p:Configuration=\"Debug\" /P:Fu=Bar"] = 0;
|
||||
actions.FileExists["csharp.log"] = true;
|
||||
actions.FileExists[@"C:\Program Files (x86)\Microsoft Visual Studio\Installer\vswhere.exe"] = false;
|
||||
actions.FileExists[@"C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\vcvarsall.bat"] = false;
|
||||
@@ -862,7 +862,7 @@ namespace Semmle.Autobuild.CSharp.Tests
|
||||
actions.RunProcess["dotnet --info"] = 0;
|
||||
actions.RunProcess[@"dotnet clean C:\Project/test.csproj"] = 0;
|
||||
actions.RunProcess[@"dotnet restore C:\Project/test.csproj"] = 0;
|
||||
actions.RunProcess[@"dotnet build --no-incremental /p:UseSharedCompilation=false --no-restore C:\Project/test.csproj"] = 0;
|
||||
actions.RunProcess[@"dotnet build --no-incremental --no-restore C:\Project/test.csproj"] = 0;
|
||||
actions.FileExists["csharp.log"] = true;
|
||||
actions.FileExists[@"C:\Project/test.csproj"] = true;
|
||||
actions.GetEnvironmentVariable["CODEQL_EXTRACTOR_CSHARP_TRAP_DIR"] = "";
|
||||
@@ -894,7 +894,7 @@ namespace Semmle.Autobuild.CSharp.Tests
|
||||
actions.RunProcess[@"C:\Project/.dotnet/dotnet --info"] = 0;
|
||||
actions.RunProcess[@"C:\Project/.dotnet/dotnet clean C:\Project/test.csproj"] = 0;
|
||||
actions.RunProcess[@"C:\Project/.dotnet/dotnet restore C:\Project/test.csproj"] = 0;
|
||||
actions.RunProcess[@"C:\Project/.dotnet/dotnet build --no-incremental /p:UseSharedCompilation=false C:\Project/test.csproj"] = 0;
|
||||
actions.RunProcess[@"C:\Project/.dotnet/dotnet build --no-incremental C:\Project/test.csproj"] = 0;
|
||||
actions.FileExists["csharp.log"] = true;
|
||||
actions.FileExists["test.csproj"] = true;
|
||||
actions.GetEnvironmentVariable["CODEQL_EXTRACTOR_CSHARP_TRAP_DIR"] = "";
|
||||
@@ -929,7 +929,7 @@ namespace Semmle.Autobuild.CSharp.Tests
|
||||
actions.RunProcess[@"C:\Project/.dotnet/dotnet --info"] = 0;
|
||||
actions.RunProcess[@"C:\Project/.dotnet/dotnet clean C:\Project/test.csproj"] = 0;
|
||||
actions.RunProcess[@"C:\Project/.dotnet/dotnet restore C:\Project/test.csproj"] = 0;
|
||||
actions.RunProcess[@"C:\Project/.dotnet/dotnet build --no-incremental /p:UseSharedCompilation=false C:\Project/test.csproj"] = 0;
|
||||
actions.RunProcess[@"C:\Project/.dotnet/dotnet build --no-incremental C:\Project/test.csproj"] = 0;
|
||||
actions.FileExists["csharp.log"] = true;
|
||||
actions.FileExists["test.csproj"] = true;
|
||||
actions.GetEnvironmentVariable["CODEQL_EXTRACTOR_CSHARP_TRAP_DIR"] = "";
|
||||
@@ -960,7 +960,7 @@ namespace Semmle.Autobuild.CSharp.Tests
|
||||
actions.RunProcess[@"cmd.exe /C C:\Project\.dotnet\dotnet --info"] = 0;
|
||||
actions.RunProcess[@"cmd.exe /C C:\Project\.dotnet\dotnet clean C:\Project\test.csproj"] = 0;
|
||||
actions.RunProcess[@"cmd.exe /C C:\Project\.dotnet\dotnet restore C:\Project\test.csproj"] = 0;
|
||||
actions.RunProcess[@"cmd.exe /C C:\Project\.dotnet\dotnet build --no-incremental /p:UseSharedCompilation=false C:\Project\test.csproj"] = 0;
|
||||
actions.RunProcess[@"cmd.exe /C C:\Project\.dotnet\dotnet build --no-incremental C:\Project\test.csproj"] = 0;
|
||||
actions.FileExists["csharp.log"] = true;
|
||||
actions.FileExists[@"C:\Project\test.csproj"] = true;
|
||||
actions.GetEnvironmentVariable["CODEQL_EXTRACTOR_CSHARP_TRAP_DIR"] = "";
|
||||
@@ -1008,7 +1008,7 @@ namespace Semmle.Autobuild.CSharp.Tests
|
||||
{
|
||||
actions.RunProcess[@"cmd.exe /C nuget restore C:\Project\dirs.proj -DisableParallelProcessing"] = 1;
|
||||
actions.RunProcess[@"cmd.exe /C C:\Project\.nuget\nuget.exe restore C:\Project\dirs.proj -DisableParallelProcessing"] = 0;
|
||||
actions.RunProcess["cmd.exe /C CALL ^\"C:\\Program Files ^(x86^)\\Microsoft Visual Studio 12.0\\VC\\vcvarsall.bat^\" && set Platform=&& type NUL && msbuild C:\\Project\\dirs.proj /p:UseSharedCompilation=false /t:Windows /p:Platform=\"x86\" /p:Configuration=\"Debug\" /p:MvcBuildViews=true /P:Fu=Bar"] = 0;
|
||||
actions.RunProcess["cmd.exe /C CALL ^\"C:\\Program Files ^(x86^)\\Microsoft Visual Studio 12.0\\VC\\vcvarsall.bat^\" && set Platform=&& type NUL && msbuild C:\\Project\\dirs.proj /t:Windows /p:Platform=\"x86\" /p:Configuration=\"Debug\" /P:Fu=Bar"] = 0;
|
||||
actions.FileExists["csharp.log"] = true;
|
||||
actions.FileExists[@"C:\Project\a\test.csproj"] = true;
|
||||
actions.FileExists[@"C:\Project\dirs.proj"] = true;
|
||||
@@ -1052,7 +1052,7 @@ namespace Semmle.Autobuild.CSharp.Tests
|
||||
{
|
||||
actions.RunProcess[@"nuget restore C:\Project/dirs.proj -DisableParallelProcessing"] = 1;
|
||||
actions.RunProcess[@"mono C:\Project/.nuget/nuget.exe restore C:\Project/dirs.proj -DisableParallelProcessing"] = 0;
|
||||
actions.RunProcess[@"msbuild C:\Project/dirs.proj /p:UseSharedCompilation=false /t:rebuild /p:MvcBuildViews=true"] = 0;
|
||||
actions.RunProcess[@"msbuild C:\Project/dirs.proj /t:rebuild"] = 0;
|
||||
actions.FileExists["csharp.log"] = true;
|
||||
actions.FileExists[@"C:\Project/a/test.csproj"] = true;
|
||||
actions.FileExists[@"C:\Project/dirs.proj"] = true;
|
||||
|
||||
@@ -5,7 +5,6 @@ using Newtonsoft.Json.Linq;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using Semmle.Util;
|
||||
using System.Text.RegularExpressions;
|
||||
using Semmle.Autobuild.Shared;
|
||||
|
||||
namespace Semmle.Autobuild.CSharp
|
||||
@@ -81,9 +80,6 @@ namespace Semmle.Autobuild.CSharp
|
||||
env = null;
|
||||
}
|
||||
|
||||
if (env is null)
|
||||
env = new Dictionary<string, string>();
|
||||
env.Add("UseSharedCompilation", "false");
|
||||
return f(installDir, env);
|
||||
});
|
||||
}
|
||||
@@ -245,8 +241,7 @@ namespace Semmle.Autobuild.CSharp
|
||||
Argument("--no-incremental");
|
||||
|
||||
return
|
||||
script.Argument("/p:UseSharedCompilation=false").
|
||||
Argument(builder.Options.DotNetArguments).
|
||||
script.Argument(builder.Options.DotNetArguments).
|
||||
QuoteArgument(projOrSln).
|
||||
Script;
|
||||
}
|
||||
|
||||
@@ -98,8 +98,6 @@ namespace Semmle.Autobuild.Shared
|
||||
command.RunCommand(msBuild);
|
||||
command.QuoteArgument(projectOrSolution.FullPath);
|
||||
|
||||
command.Argument("/p:UseSharedCompilation=false");
|
||||
|
||||
var target = builder.Options.MsBuildTarget ?? "rebuild";
|
||||
var platform = builder.Options.MsBuildPlatform ?? (projectOrSolution is ISolution s1 ? s1.DefaultPlatformName : null);
|
||||
var configuration = builder.Options.MsBuildConfiguration ?? (projectOrSolution is ISolution s2 ? s2.DefaultConfigurationName : null);
|
||||
@@ -109,7 +107,6 @@ namespace Semmle.Autobuild.Shared
|
||||
command.Argument(string.Format("/p:Platform=\"{0}\"", platform));
|
||||
if (configuration is not null)
|
||||
command.Argument(string.Format("/p:Configuration=\"{0}\"", configuration));
|
||||
command.Argument("/p:MvcBuildViews=true");
|
||||
|
||||
command.Argument(builder.Options.MsBuildArguments);
|
||||
|
||||
|
||||
@@ -35,3 +35,10 @@ options:
|
||||
the code (for example if it uses inaccessible dependencies).
|
||||
type: string
|
||||
pattern: "^(false|true)$"
|
||||
cil:
|
||||
title: Whether to enable CIL extraction.
|
||||
description: >
|
||||
A value indicating, whether CIL extraction should be enabled.
|
||||
The default is 'true'.
|
||||
type: string
|
||||
pattern: "^(false|true)$"
|
||||
|
||||
@@ -9,7 +9,7 @@ Microsoft.Extensions.Caching.Memory,,,46,,,,,,,,,,,,45,1
|
||||
Microsoft.Extensions.Configuration,,,83,,,,,,,,,,,,80,3
|
||||
Microsoft.Extensions.DependencyInjection,,,62,,,,,,,,,,,,62,
|
||||
Microsoft.Extensions.DependencyModel,,,12,,,,,,,,,,,,12,
|
||||
Microsoft.Extensions.FileProviders,,,15,,,,,,,,,,,,15,
|
||||
Microsoft.Extensions.FileProviders,,,16,,,,,,,,,,,,16,
|
||||
Microsoft.Extensions.FileSystemGlobbing,,,15,,,,,,,,,,,,13,2
|
||||
Microsoft.Extensions.Hosting,,,17,,,,,,,,,,,,16,1
|
||||
Microsoft.Extensions.Http,,,10,,,,,,,,,,,,10,
|
||||
@@ -24,5 +24,5 @@ Microsoft.Win32,,,8,,,,,,,,,,,,8,
|
||||
MySql.Data.MySqlClient,48,,,,,,,,,,48,,,,,
|
||||
Newtonsoft.Json,,,91,,,,,,,,,,,,73,18
|
||||
ServiceStack,194,,7,27,,,,,,75,92,,,,7,
|
||||
System,43,4,11809,,1,1,1,,4,,33,3,1,3,9867,1942
|
||||
System,65,4,12081,,8,8,9,,4,,33,3,1,3,10139,1942
|
||||
Windows.Security.Cryptography.Core,1,,,,,,,1,,,,,,,,
|
||||
|
||||
|
@@ -8,7 +8,7 @@ C# framework & library support
|
||||
|
||||
Framework / library,Package,Flow sources,Taint & value steps,Sinks (total),`CWE-079` :sub:`Cross-site scripting`
|
||||
`ServiceStack <https://servicestack.net/>`_,"``ServiceStack.*``, ``ServiceStack``",,7,194,
|
||||
System,"``System.*``, ``System``",4,11809,43,7
|
||||
Others,"``Dapper``, ``JsonToItemsTaskFactory``, ``Microsoft.ApplicationBlocks.Data``, ``Microsoft.CSharp``, ``Microsoft.EntityFrameworkCore``, ``Microsoft.Extensions.Caching.Distributed``, ``Microsoft.Extensions.Caching.Memory``, ``Microsoft.Extensions.Configuration``, ``Microsoft.Extensions.DependencyInjection``, ``Microsoft.Extensions.DependencyModel``, ``Microsoft.Extensions.FileProviders``, ``Microsoft.Extensions.FileSystemGlobbing``, ``Microsoft.Extensions.Hosting``, ``Microsoft.Extensions.Http``, ``Microsoft.Extensions.Logging``, ``Microsoft.Extensions.Options``, ``Microsoft.Extensions.Primitives``, ``Microsoft.Interop``, ``Microsoft.NET.Build.Tasks``, ``Microsoft.NETCore.Platforms.BuildTasks``, ``Microsoft.VisualBasic``, ``Microsoft.Win32``, ``MySql.Data.MySqlClient``, ``Newtonsoft.Json``, ``Windows.Security.Cryptography.Core``",,554,138,
|
||||
Totals,,4,12370,375,7
|
||||
System,"``System.*``, ``System``",4,12081,65,7
|
||||
Others,"``Dapper``, ``JsonToItemsTaskFactory``, ``Microsoft.ApplicationBlocks.Data``, ``Microsoft.CSharp``, ``Microsoft.EntityFrameworkCore``, ``Microsoft.Extensions.Caching.Distributed``, ``Microsoft.Extensions.Caching.Memory``, ``Microsoft.Extensions.Configuration``, ``Microsoft.Extensions.DependencyInjection``, ``Microsoft.Extensions.DependencyModel``, ``Microsoft.Extensions.FileProviders``, ``Microsoft.Extensions.FileSystemGlobbing``, ``Microsoft.Extensions.Hosting``, ``Microsoft.Extensions.Http``, ``Microsoft.Extensions.Logging``, ``Microsoft.Extensions.Options``, ``Microsoft.Extensions.Primitives``, ``Microsoft.Interop``, ``Microsoft.NET.Build.Tasks``, ``Microsoft.NETCore.Platforms.BuildTasks``, ``Microsoft.VisualBasic``, ``Microsoft.Win32``, ``MySql.Data.MySqlClient``, ``Newtonsoft.Json``, ``Windows.Security.Cryptography.Core``",,555,138,
|
||||
Totals,,4,12643,397,7
|
||||
|
||||
|
||||
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: Introduce '--cil' flag in the comments. This does not make any changes to the dbscheme.
|
||||
compatibility: full
|
||||
@@ -13,31 +13,6 @@ namespace Semmle.Extraction.CSharp
|
||||
{
|
||||
Extractor.SetInvariantCulture();
|
||||
|
||||
Console.WriteLine($"Semmle.Extraction.CSharp.Driver: called with {string.Join(", ", args)}");
|
||||
|
||||
if (args.Length > 0 && args[0] == "--dotnetexec")
|
||||
{
|
||||
var compilerRegEx = new Regex(@"csc\.exe|mcs\.exe|csc\.dll", RegexOptions.Compiled);
|
||||
var cil = args.Length > 1 && args[1] == "--cil";
|
||||
for (var i = cil ? 2 : 1; i < args.Length; i++)
|
||||
{
|
||||
if (compilerRegEx.IsMatch(args[i]))
|
||||
{
|
||||
var argsList = new List<string>();
|
||||
if (cil)
|
||||
argsList.Add("--cil");
|
||||
argsList.Add("--compiler");
|
||||
argsList.Add(args[i]);
|
||||
if (i + 1 < args.Length)
|
||||
argsList.AddRange(args[(i + 1)..]);
|
||||
return (int)Extractor.Run(argsList.ToArray());
|
||||
}
|
||||
}
|
||||
|
||||
Console.WriteLine($"Semmle.Extraction.CSharp.Driver: not a compiler invocation");
|
||||
return 0;
|
||||
}
|
||||
|
||||
return (int)Extractor.Run(args);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -56,7 +56,6 @@ namespace Semmle.Extraction.CSharp.Standalone
|
||||
CSharp.Extractor.SetInvariantCulture();
|
||||
|
||||
var options = Options.Create(args);
|
||||
// options.CIL = true; // To do: Enable this
|
||||
|
||||
if (options.Help)
|
||||
{
|
||||
|
||||
@@ -22,7 +22,7 @@ namespace Semmle.Extraction.Tests
|
||||
{
|
||||
options = CSharp.Options.CreateWithEnvironment(Array.Empty<string>());
|
||||
Assert.True(options.Cache);
|
||||
Assert.False(options.CIL);
|
||||
Assert.True(options.CIL);
|
||||
Assert.Null(options.Framework);
|
||||
Assert.Null(options.CompilerName);
|
||||
Assert.Empty(options.CompilerArguments);
|
||||
@@ -51,10 +51,20 @@ namespace Semmle.Extraction.Tests
|
||||
[Fact]
|
||||
public void CIL()
|
||||
{
|
||||
options = CSharp.Options.CreateWithEnvironment(new string[] { "--cil" });
|
||||
options = CSharp.Options.CreateWithEnvironment(Array.Empty<string>());
|
||||
Assert.True(options.CIL);
|
||||
options = CSharp.Options.CreateWithEnvironment(new string[] { "--cil", "--nocil" });
|
||||
|
||||
Environment.SetEnvironmentVariable("CODEQL_EXTRACTOR_CSHARP_OPTION_CIL", "false");
|
||||
options = CSharp.Options.CreateWithEnvironment(Array.Empty<string>());
|
||||
Assert.False(options.CIL);
|
||||
|
||||
Environment.SetEnvironmentVariable("CODEQL_EXTRACTOR_CSHARP_OPTION_CIL", "true");
|
||||
options = CSharp.Options.CreateWithEnvironment(Array.Empty<string>());
|
||||
Assert.True(options.CIL);
|
||||
|
||||
Environment.SetEnvironmentVariable("CODEQL_EXTRACTOR_CSHARP_OPTION_CIL", null);
|
||||
options = CSharp.Options.CreateWithEnvironment(Array.Empty<string>());
|
||||
Assert.True(options.CIL);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
@@ -121,22 +131,6 @@ namespace Semmle.Extraction.Tests
|
||||
Assert.Equal("foo", options.Framework);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void EnvironmentVariables()
|
||||
{
|
||||
Environment.SetEnvironmentVariable("LGTM_INDEX_EXTRACTOR", "--cil c");
|
||||
options = CSharp.Options.CreateWithEnvironment(new string[] { "a", "b" });
|
||||
Assert.True(options.CIL);
|
||||
Assert.Equal("a", options.CompilerArguments[0]);
|
||||
Assert.Equal("b", options.CompilerArguments[1]);
|
||||
Assert.Equal("c", options.CompilerArguments[2]);
|
||||
|
||||
Environment.SetEnvironmentVariable("LGTM_INDEX_EXTRACTOR", "");
|
||||
Environment.SetEnvironmentVariable("LGTM_INDEX_EXTRACTOR", "--nocil");
|
||||
options = CSharp.Options.CreateWithEnvironment(new string[] { "--cil" });
|
||||
Assert.False(options.CIL);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void StandaloneDefaults()
|
||||
{
|
||||
|
||||
@@ -28,7 +28,7 @@ namespace Semmle.Extraction
|
||||
/// <summary>
|
||||
/// Holds if CIL should be extracted.
|
||||
/// </summary>
|
||||
public bool CIL { get; private set; } = false;
|
||||
public bool CIL { get; private set; } = true;
|
||||
|
||||
/// <summary>
|
||||
/// Holds if assemblies shouldn't be extracted twice.
|
||||
@@ -50,7 +50,6 @@ namespace Semmle.Extraction
|
||||
/// </summary>
|
||||
public bool QlTest { get; private set; } = false;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// The compression algorithm used for trap files.
|
||||
/// </summary>
|
||||
@@ -73,6 +72,9 @@ namespace Semmle.Extraction
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
case "cil":
|
||||
CIL = Boolean.Parse(value);
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
@@ -97,9 +99,6 @@ namespace Semmle.Extraction
|
||||
case "cache":
|
||||
Cache = value;
|
||||
return true;
|
||||
case "cil":
|
||||
CIL = value;
|
||||
return true;
|
||||
case "pdb":
|
||||
PDB = value;
|
||||
CIL = true;
|
||||
|
||||
@@ -17,7 +17,7 @@ namespace Semmle.Util
|
||||
bool HandleOption(string key, string value);
|
||||
|
||||
/// <summary>
|
||||
/// Handle a flag of the form "--cil" or "--nocil"
|
||||
/// Handle a flag of the form "--cache" or "--nocache"
|
||||
/// </summary>
|
||||
/// <param name="key">The name of the flag. This is case sensitive.</param>
|
||||
/// <param name="value">True if set, or false if prefixed by "--no"</param>
|
||||
@@ -40,6 +40,7 @@ namespace Semmle.Util
|
||||
|
||||
public static class OptionsExtensions
|
||||
{
|
||||
private static readonly string[] ExtractorOptions = new[] { "trap_compression", "cil" };
|
||||
private static string? GetExtractorOption(string name) =>
|
||||
Environment.GetEnvironmentVariable($"CODEQL_EXTRACTOR_CSHARP_OPTION_{name.ToUpper()}");
|
||||
|
||||
@@ -47,12 +48,14 @@ namespace Semmle.Util
|
||||
{
|
||||
var extractorOptions = new List<string>();
|
||||
|
||||
var trapCompression = GetExtractorOption("trap_compression");
|
||||
if (!string.IsNullOrEmpty(trapCompression))
|
||||
foreach (var option in ExtractorOptions)
|
||||
{
|
||||
extractorOptions.Add($"--trap_compression:{trapCompression}");
|
||||
var value = GetExtractorOption(option);
|
||||
if (!string.IsNullOrEmpty(value))
|
||||
{
|
||||
extractorOptions.Add($"--{option}:{value}");
|
||||
}
|
||||
}
|
||||
|
||||
return extractorOptions;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
## 1.2.4
|
||||
|
||||
## 1.2.3
|
||||
|
||||
## 1.2.2
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
## 1.2.4
|
||||
@@ -1,2 +1,2 @@
|
||||
---
|
||||
lastReleaseVersion: 1.2.3
|
||||
lastReleaseVersion: 1.2.4
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
name: codeql/csharp-solorigate-all
|
||||
version: 1.2.4-dev
|
||||
version: 1.2.5-dev
|
||||
groups:
|
||||
- csharp
|
||||
- solorigate
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
## 1.2.4
|
||||
|
||||
## 1.2.3
|
||||
|
||||
## 1.2.2
|
||||
|
||||
@@ -15,7 +15,7 @@ import experimental.code.csharp.Cryptography.NonCryptographicHashes
|
||||
|
||||
from Variable v, Literal l, LoopStmt loop, Expr additional_xor
|
||||
where
|
||||
maybeUsedInFNVFunction(v, _, _, loop) and
|
||||
maybeUsedInFnvFunction(v, _, _, loop) and
|
||||
(
|
||||
exists(BitwiseXorExpr xor2 | xor2.getAnOperand() = l and additional_xor = xor2 |
|
||||
loop.getAControlFlowExitNode().getASuccessor*() = xor2.getAControlFlowNode() and
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
## 1.2.4
|
||||
@@ -1,2 +1,2 @@
|
||||
---
|
||||
lastReleaseVersion: 1.2.3
|
||||
lastReleaseVersion: 1.2.4
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
name: codeql/csharp-solorigate-queries
|
||||
version: 1.2.4-dev
|
||||
version: 1.2.5-dev
|
||||
groups:
|
||||
- csharp
|
||||
- solorigate
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import csharp
|
||||
import semmle.code.csharp.dataflow.internal.SsaImplCommon::Consistency
|
||||
import semmle.code.csharp.dataflow.internal.SsaImpl::Consistency as Consistency
|
||||
import Ssa
|
||||
|
||||
class MyRelevantDefinition extends RelevantDefinition, Ssa::Definition {
|
||||
class MyRelevantDefinition extends Consistency::RelevantDefinition, Ssa::Definition {
|
||||
override predicate hasLocationInfo(
|
||||
string filepath, int startline, int startcolumn, int endline, int endcolumn
|
||||
) {
|
||||
@@ -10,6 +10,14 @@ class MyRelevantDefinition extends RelevantDefinition, Ssa::Definition {
|
||||
}
|
||||
}
|
||||
|
||||
query predicate nonUniqueDef = Consistency::nonUniqueDef/4;
|
||||
|
||||
query predicate readWithoutDef = Consistency::readWithoutDef/3;
|
||||
|
||||
query predicate deadDef = Consistency::deadDef/2;
|
||||
|
||||
query predicate notDominatedByDef = Consistency::notDominatedByDef/4;
|
||||
|
||||
query predicate localDeclWithSsaDef(LocalVariableDeclExpr d) {
|
||||
// Local variables in C# must be initialized before every use, so uninitialized
|
||||
// local variables should not have an SSA definition, as that would imply that
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
Console.WriteLine(args[0]);
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user