mirror of
https://github.com/github/codeql.git
synced 2026-05-30 02:51:24 +02:00
Compare commits
423 Commits
jhelie/tes
...
jhelie/val
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
74a7f83631 | ||
|
|
0e15bb8b9e | ||
|
|
edc8f6f0f2 | ||
|
|
33f5620782 | ||
|
|
c56e0f7c0d | ||
|
|
95db81658b | ||
|
|
43ae5d4285 | ||
|
|
3f6925e7be | ||
|
|
715b0b3fb8 | ||
|
|
3af2e71932 | ||
|
|
8cd0a9d245 | ||
|
|
a61ec78f03 | ||
|
|
fe73601a4e | ||
|
|
681e58c8e0 | ||
|
|
cb3ebeedf9 | ||
|
|
db41ce5f76 | ||
|
|
6cfde70898 | ||
|
|
b4d762fb21 | ||
|
|
0c0ba925a7 | ||
|
|
f39ca1aad2 | ||
|
|
0a35f97074 | ||
|
|
c2710fb038 | ||
|
|
2c095cf166 | ||
|
|
a9d95a9418 | ||
|
|
23c19311fb | ||
|
|
4767d5a1ba | ||
|
|
43266b75a1 | ||
|
|
5f9a03f103 | ||
|
|
77401ded4e | ||
|
|
d44bf326f0 | ||
|
|
7e67338fb5 | ||
|
|
871b6515d5 | ||
|
|
1842bde879 | ||
|
|
c1a6ca5f94 | ||
|
|
486a394a7f | ||
|
|
8fabc06d37 | ||
|
|
cc958dc171 | ||
|
|
1399610bd4 | ||
|
|
5f96c92fac | ||
|
|
ed0325f162 | ||
|
|
7be106d7bb | ||
|
|
27be3dff54 | ||
|
|
8dae85e1b1 | ||
|
|
0a8ecd3cf7 | ||
|
|
388c9ffb74 | ||
|
|
ad8335d6f3 | ||
|
|
466eb4a845 | ||
|
|
a437fcbbcc | ||
|
|
9593ceeda5 | ||
|
|
1cbe26a54f | ||
|
|
4d0f6a0b96 | ||
|
|
a10370f813 | ||
|
|
b3f2159a7e | ||
|
|
17c80336f5 | ||
|
|
8d80e0332e | ||
|
|
a1d9228a66 | ||
|
|
694d6395d5 | ||
|
|
8c55a15fa6 | ||
|
|
6f74a2609c | ||
|
|
f54fc1a88d | ||
|
|
c2b7300709 | ||
|
|
e9e5d948b3 | ||
|
|
ca819573f5 | ||
|
|
3527897eff | ||
|
|
7620a6f653 | ||
|
|
aa53841466 | ||
|
|
018a76bb17 | ||
|
|
dcc76ddf36 | ||
|
|
0828474192 | ||
|
|
43a9b8960e | ||
|
|
cf23d338f3 | ||
|
|
6bc2fe513d | ||
|
|
b9bdee6651 | ||
|
|
03bf9eb166 | ||
|
|
bfe90413e2 | ||
|
|
dcbd82907f | ||
|
|
ec1d1eb547 | ||
|
|
962155fd61 | ||
|
|
9586259706 | ||
|
|
304203ad2f | ||
|
|
7b8603c89b | ||
|
|
f9b6ca76e5 | ||
|
|
fc00e56058 | ||
|
|
c9e5206396 | ||
|
|
541df9b550 | ||
|
|
336548f746 | ||
|
|
9474e63faf | ||
|
|
b136790efd | ||
|
|
0bd94a6307 | ||
|
|
4854679a40 | ||
|
|
39fb714ad1 | ||
|
|
e1bd4a78ff | ||
|
|
410167671f | ||
|
|
eebba36b18 | ||
|
|
98fc8812fc | ||
|
|
c779936ee8 | ||
|
|
c08c3955d6 | ||
|
|
78fc356feb | ||
|
|
dbd6607875 | ||
|
|
cc5f59f313 | ||
|
|
d4443592eb | ||
|
|
6b17890e4f | ||
|
|
eefa659503 | ||
|
|
fe789c8aa9 | ||
|
|
b897a40228 | ||
|
|
2f50549184 | ||
|
|
a1df1d1119 | ||
|
|
ee1c09329f | ||
|
|
d50816a284 | ||
|
|
0ee476129a | ||
|
|
d13f9d5d71 | ||
|
|
7fbe4f8547 | ||
|
|
592ce3ec58 | ||
|
|
22ff8c2c7e | ||
|
|
3e06455ac1 | ||
|
|
21066d277f | ||
|
|
5ba4f6dae8 | ||
|
|
fd7561cf27 | ||
|
|
a7a9428dc1 | ||
|
|
47c9b446f0 | ||
|
|
380070f2e4 | ||
|
|
dbff20a3d8 | ||
|
|
9f184ec122 | ||
|
|
fe1f1bb79d | ||
|
|
33fdcf1e4f | ||
|
|
d1aa0d7dd3 | ||
|
|
855d4c2ea1 | ||
|
|
43a82004b2 | ||
|
|
18c5a8c8da | ||
|
|
da8123072d | ||
|
|
f1144b9672 | ||
|
|
d748cb483d | ||
|
|
4c53c341f6 | ||
|
|
62a10e20b2 | ||
|
|
8ca7d7d775 | ||
|
|
9d277027a3 | ||
|
|
3dd61cadf4 | ||
|
|
9a186ba5d2 | ||
|
|
ee79834cc8 | ||
|
|
ae634367c9 | ||
|
|
2cc703387b | ||
|
|
f5301aa478 | ||
|
|
80cbddf626 | ||
|
|
f7c47b6c75 | ||
|
|
f9da4a0456 | ||
|
|
b1dd3c2d84 | ||
|
|
9e2e32f037 | ||
|
|
6dd09c1815 | ||
|
|
3e4a182ee8 | ||
|
|
5773a734c3 | ||
|
|
f7dca4d70f | ||
|
|
1fa2144716 | ||
|
|
fd10947ca0 | ||
|
|
cd5fbe633f | ||
|
|
c4f44bb67f | ||
|
|
a49d34cf0f | ||
|
|
dded3af3d8 | ||
|
|
047b14e310 | ||
|
|
eb0340dcb6 | ||
|
|
878168384e | ||
|
|
2850b35a04 | ||
|
|
49aab51893 | ||
|
|
ea95e2e1d0 | ||
|
|
b9fc82a741 | ||
|
|
4cfaa86d5d | ||
|
|
5f17d8370c | ||
|
|
63dcce9a31 | ||
|
|
b5a3d3c488 | ||
|
|
301914d80c | ||
|
|
706d1d2eee | ||
|
|
0dbb03f732 | ||
|
|
7df7b92d86 | ||
|
|
7129002573 | ||
|
|
b3f1a513d1 | ||
|
|
9a0a9491da | ||
|
|
2566ae9889 | ||
|
|
db5f63b208 | ||
|
|
7facc63699 | ||
|
|
2aaedacd5d | ||
|
|
89043ec4ef | ||
|
|
74d6061082 | ||
|
|
5cbe01d8dc | ||
|
|
e092cb02cd | ||
|
|
a4adf06713 | ||
|
|
c18428f1a9 | ||
|
|
d929b1338b | ||
|
|
64343e00f4 | ||
|
|
8a48708014 | ||
|
|
2bac181094 | ||
|
|
a4e35a97ea | ||
|
|
a51d713925 | ||
|
|
f7c4fa691d | ||
|
|
a0636ff843 | ||
|
|
8f9d419441 | ||
|
|
e5eabc4e47 | ||
|
|
d63b0946d9 | ||
|
|
2ceb25dc9a | ||
|
|
d0bf424b19 | ||
|
|
1bcb17b760 | ||
|
|
48c71c9407 | ||
|
|
de6a9375ba | ||
|
|
2edeeaac0e | ||
|
|
965f5a980a | ||
|
|
2ddcf8364c | ||
|
|
033b239b22 | ||
|
|
685389d219 | ||
|
|
c75599c3da | ||
|
|
217c9a8aaf | ||
|
|
47a4cac8ee | ||
|
|
70838fe57f | ||
|
|
d5791e2d56 | ||
|
|
02e11b7ee9 | ||
|
|
ac05577966 | ||
|
|
e5702d0e15 | ||
|
|
7fc9ae6c49 | ||
|
|
022acf2de0 | ||
|
|
960d1dba8a | ||
|
|
4c68624b00 | ||
|
|
b9072a3594 | ||
|
|
4704269086 | ||
|
|
a3628b06f1 | ||
|
|
032aa56dc3 | ||
|
|
6632dfaf88 | ||
|
|
5d89a5d164 | ||
|
|
156bc34cda | ||
|
|
ad7c3e7217 | ||
|
|
539fbbc126 | ||
|
|
348ad95fc0 | ||
|
|
93d06daf67 | ||
|
|
39406436bf | ||
|
|
a6048dd594 | ||
|
|
93a4a32527 | ||
|
|
bbd7e62341 | ||
|
|
28a8999b74 | ||
|
|
aa07600f5a | ||
|
|
9ed7aa9fae | ||
|
|
74641ccfee | ||
|
|
6b2154eb8b | ||
|
|
7d5dd384c3 | ||
|
|
7c3cadc9b6 | ||
|
|
e8e8da1b31 | ||
|
|
5d3232c614 | ||
|
|
96e66c4a50 | ||
|
|
0435105d16 | ||
|
|
6aab970a9e | ||
|
|
bd50fd7f1e | ||
|
|
11e39aa030 | ||
|
|
940254d251 | ||
|
|
b4869158f2 | ||
|
|
2f1cfa816f | ||
|
|
f8994d04d6 | ||
|
|
4379aa4398 | ||
|
|
01da877d0e | ||
|
|
0b471c2007 | ||
|
|
7d6fb7f91a | ||
|
|
74ff579dbc | ||
|
|
dd1a9a22e3 | ||
|
|
f5c6b45014 | ||
|
|
56060e0610 | ||
|
|
3bacb18315 | ||
|
|
4d45a2ca87 | ||
|
|
e43e5810cf | ||
|
|
e98bdbf73f | ||
|
|
e38254c05e | ||
|
|
1730ec22d9 | ||
|
|
b499ba5aa8 | ||
|
|
c393c9b03e | ||
|
|
2dca78295d | ||
|
|
e88cc31468 | ||
|
|
563d27333a | ||
|
|
34ffd1aac5 | ||
|
|
d60d2457c2 | ||
|
|
bc03f6959c | ||
|
|
a306f312cd | ||
|
|
416977dc50 | ||
|
|
8addc06799 | ||
|
|
227dad8bf5 | ||
|
|
7a1c3800e6 | ||
|
|
e575bab9d6 | ||
|
|
f9143f7855 | ||
|
|
4c6a9772af | ||
|
|
3a975174c3 | ||
|
|
7a7440a115 | ||
|
|
24da81fdb0 | ||
|
|
901e066355 | ||
|
|
5b5a52fa25 | ||
|
|
7dd095c0d2 | ||
|
|
e4636be8db | ||
|
|
14aef792e0 | ||
|
|
df78b7e54b | ||
|
|
8336c67edb | ||
|
|
b9eec13466 | ||
|
|
dd93062101 | ||
|
|
144c0d63b1 | ||
|
|
ef0ec396c4 | ||
|
|
08b1c5495a | ||
|
|
57e026d617 | ||
|
|
9b424ac8b2 | ||
|
|
92a9738bd5 | ||
|
|
3bb51c2643 | ||
|
|
b373af47d1 | ||
|
|
570e418b22 | ||
|
|
ec95cbace4 | ||
|
|
0d0d240fd4 | ||
|
|
83fd9c3b3e | ||
|
|
6b5785bffa | ||
|
|
eaec1ac561 | ||
|
|
cf9b69b5f2 | ||
|
|
b0a29b146a | ||
|
|
df7ffb2880 | ||
|
|
0e56e50d18 | ||
|
|
8214c3b78e | ||
|
|
98761041f1 | ||
|
|
bf581b971c | ||
|
|
5a47e1dd95 | ||
|
|
466cf7573b | ||
|
|
b4124ac553 | ||
|
|
bfdb21d551 | ||
|
|
28c05e7a56 | ||
|
|
68c76006bd | ||
|
|
0251fb2d35 | ||
|
|
2bd25fc589 | ||
|
|
51e3ff9d09 | ||
|
|
5a04d62969 | ||
|
|
133a6caaa3 | ||
|
|
ab52a020fa | ||
|
|
8e5bbea9f9 | ||
|
|
2d98eb591e | ||
|
|
02dd933e5f | ||
|
|
11be15aab1 | ||
|
|
f71a64b99d | ||
|
|
22d285f777 | ||
|
|
7cef4322e7 | ||
|
|
41244180b3 | ||
|
|
4dcec2b98c | ||
|
|
5db2f9a768 | ||
|
|
c1302a90e0 | ||
|
|
1105cd569b | ||
|
|
ac0c8d238f | ||
|
|
0f8ffb12e6 | ||
|
|
363f7a88a9 | ||
|
|
a7956ad422 | ||
|
|
82c9b8b494 | ||
|
|
a7bd2030b6 | ||
|
|
834d2603a2 | ||
|
|
c33690381e | ||
|
|
c1a2e2abe0 | ||
|
|
fd28397056 | ||
|
|
9cf48fc804 | ||
|
|
b1251f0c63 | ||
|
|
67b6f215dc | ||
|
|
43bb439b82 | ||
|
|
3c9e743495 | ||
|
|
17d139c87d | ||
|
|
9e154ff4bd | ||
|
|
280c959dc8 | ||
|
|
d92430b0e7 | ||
|
|
9e4116618a | ||
|
|
c1515db09c | ||
|
|
03d0f66247 | ||
|
|
6ea1aad5fc | ||
|
|
ce2edd4b28 | ||
|
|
ca074e2275 | ||
|
|
cf36333082 | ||
|
|
45dd38df6e | ||
|
|
e838b83f5f | ||
|
|
995f365568 | ||
|
|
c767f241ad | ||
|
|
f6c4b5c44b | ||
|
|
990747cd22 | ||
|
|
53729f99c5 | ||
|
|
bbe17b3667 | ||
|
|
83b720d730 | ||
|
|
1ec838e671 | ||
|
|
73b657ce25 | ||
|
|
3547c338ef | ||
|
|
9d6b1bf142 | ||
|
|
7d62b9e131 | ||
|
|
94145e9e74 | ||
|
|
6d3808bd89 | ||
|
|
15f9e084d5 | ||
|
|
f8b451a514 | ||
|
|
f08f02ed66 | ||
|
|
115110475d | ||
|
|
26df367a8a | ||
|
|
1856e2b389 | ||
|
|
6e2f3e2fcb | ||
|
|
638a886dfe | ||
|
|
0391db6787 | ||
|
|
7e93416e97 | ||
|
|
a59f0d36f5 | ||
|
|
3a4f0299c7 | ||
|
|
3478e7e910 | ||
|
|
0456870136 | ||
|
|
ecb2114b7b | ||
|
|
8b36191023 | ||
|
|
059c4d38ad | ||
|
|
8aa2602d9e | ||
|
|
4733653939 | ||
|
|
e4462b7aac | ||
|
|
5931ea4ab8 | ||
|
|
b993558987 | ||
|
|
0608d4d2f9 | ||
|
|
40b61fa85f | ||
|
|
f4ce382b7d | ||
|
|
b524fb4f3a | ||
|
|
304e2926c9 | ||
|
|
7b5d9ec7df | ||
|
|
6bef71ea2c | ||
|
|
7bdec98e6f | ||
|
|
c012c235c6 | ||
|
|
4b50c68934 | ||
|
|
2a196611af | ||
|
|
86c8737250 | ||
|
|
35c3c62f9e | ||
|
|
daed33f5af | ||
|
|
3762ce2c72 | ||
|
|
f204a41122 | ||
|
|
53760799fc | ||
|
|
efba220b45 | ||
|
|
ecd3aceb07 | ||
|
|
af112a011a | ||
|
|
8c6022b78a |
1
.github/workflows/check-change-note.yml
vendored
1
.github/workflows/check-change-note.yml
vendored
@@ -10,6 +10,7 @@ on:
|
||||
- "*/ql/lib/**/*.qll"
|
||||
- "!**/experimental/**"
|
||||
- "!ql/**"
|
||||
- "!swift/**"
|
||||
- ".github/workflows/check-change-note.yml"
|
||||
|
||||
jobs:
|
||||
|
||||
63
.github/workflows/ql-for-ql-build.yml
vendored
63
.github/workflows/ql-for-ql-build.yml
vendored
@@ -10,16 +10,16 @@ env:
|
||||
CARGO_TERM_COLOR: always
|
||||
|
||||
jobs:
|
||||
queries:
|
||||
runs-on: ubuntu-latest
|
||||
analyze:
|
||||
runs-on: ubuntu-latest-xl
|
||||
steps:
|
||||
### Build the queries ###
|
||||
- uses: actions/checkout@v3
|
||||
- name: Find codeql
|
||||
id: find-codeql
|
||||
uses: github/codeql-action/init@aa93aea877e5fb8841bcb1193f672abf6e9f2980
|
||||
with:
|
||||
languages: javascript # does not matter
|
||||
tools: latest
|
||||
- name: Get CodeQL version
|
||||
id: get-codeql-version
|
||||
run: |
|
||||
@@ -49,14 +49,7 @@ jobs:
|
||||
name: query-pack-zip
|
||||
path: ${{ runner.temp }}/query-pack.zip
|
||||
|
||||
extractors:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
### Build the extractor ###
|
||||
- name: Cache entire extractor
|
||||
id: cache-extractor
|
||||
uses: actions/cache@v3
|
||||
@@ -100,15 +93,8 @@ jobs:
|
||||
ql/target/release/ql-extractor
|
||||
ql/target/release/ql-extractor.exe
|
||||
retention-days: 1
|
||||
package:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
needs:
|
||||
- extractors
|
||||
- queries
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
### Package the queries and extractor ###
|
||||
- uses: actions/download-artifact@v3
|
||||
with:
|
||||
name: query-pack-zip
|
||||
@@ -136,16 +122,8 @@ jobs:
|
||||
name: codeql-ql-pack
|
||||
path: codeql-ql.zip
|
||||
retention-days: 1
|
||||
analyze:
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
matrix:
|
||||
folder: [cpp, csharp, java, javascript, python, ql, ruby, swift, go]
|
||||
|
||||
needs:
|
||||
- package
|
||||
|
||||
steps:
|
||||
### Run the analysis ###
|
||||
- name: Download pack
|
||||
uses: actions/download-artifact@v3
|
||||
with:
|
||||
@@ -165,14 +143,11 @@ jobs:
|
||||
env:
|
||||
PACK: ${{ runner.temp }}/pack
|
||||
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v3
|
||||
- name: Create CodeQL config file
|
||||
run: |
|
||||
echo "paths:" > ${CONF}
|
||||
echo " - ${FOLDER}" >> ${CONF}
|
||||
echo "paths-ignore:" >> ${CONF}
|
||||
echo " - ql/ql/test" >> ${CONF}
|
||||
echo " - \"*/ql/lib/upgrades/\"" >> ${CONF}
|
||||
echo "disable-default-queries: true" >> ${CONF}
|
||||
echo "packs:" >> ${CONF}
|
||||
echo " - codeql/ql" >> ${CONF}
|
||||
@@ -180,24 +155,34 @@ jobs:
|
||||
cat ${CONF}
|
||||
env:
|
||||
CONF: ./ql-for-ql-config.yml
|
||||
FOLDER: ${{ matrix.folder }}
|
||||
- name: Initialize CodeQL
|
||||
uses: github/codeql-action/init@aa93aea877e5fb8841bcb1193f672abf6e9f2980
|
||||
with:
|
||||
languages: ql
|
||||
db-location: ${{ runner.temp }}/db
|
||||
config-file: ./ql-for-ql-config.yml
|
||||
tools: latest
|
||||
|
||||
- name: Perform CodeQL Analysis
|
||||
uses: github/codeql-action/analyze@aa93aea877e5fb8841bcb1193f672abf6e9f2980
|
||||
with:
|
||||
category: "ql-for-ql-${{ matrix.folder }}"
|
||||
category: "ql-for-ql"
|
||||
- name: Copy sarif file to CWD
|
||||
run: cp ../results/ql.sarif ./${{ matrix.folder }}.sarif
|
||||
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
|
||||
- name: Sarif as artifact
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: ${{ matrix.folder }}.sarif
|
||||
path: ${{ matrix.folder }}.sarif
|
||||
|
||||
name: ql-for-ql.sarif
|
||||
path: ql-for-ql.sarif
|
||||
- name: Split out the sarif file into langs
|
||||
run: |
|
||||
mkdir split-sarif
|
||||
node ./ql/scripts/split-sarif.js ql-for-ql.sarif split-sarif
|
||||
- name: Upload langs as artifacts
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: ql-for-ql-langs
|
||||
path: split-sarif
|
||||
retention-days: 1
|
||||
@@ -36,7 +36,7 @@ jobs:
|
||||
ql/target
|
||||
key: ${{ runner.os }}-qltest-cargo-${{ hashFiles('ql/**/Cargo.lock') }}
|
||||
- name: Build Extractor
|
||||
run: cd ql; env "PATH=$PATH:`dirname ${CODEQL}`" ./create-extractor-pack.sh
|
||||
run: cd ql; env "PATH=$PATH:`dirname ${CODEQL}`" ./scripts/create-extractor-pack.sh
|
||||
env:
|
||||
CODEQL: ${{ steps.find-codeql.outputs.codeql-path }}
|
||||
- name: Checkout ${{ matrix.repo }}
|
||||
|
||||
2
.github/workflows/ql-for-ql-tests.yml
vendored
2
.github/workflows/ql-for-ql-tests.yml
vendored
@@ -36,7 +36,7 @@ jobs:
|
||||
run: |
|
||||
cd ql;
|
||||
codeqlpath=$(dirname ${{ steps.find-codeql.outputs.codeql-path }});
|
||||
env "PATH=$PATH:$codeqlpath" ./create-extractor-pack.sh
|
||||
env "PATH=$PATH:$codeqlpath" ./scripts/create-extractor-pack.sh
|
||||
- name: Run QL tests
|
||||
run: |
|
||||
"${CODEQL}" test run --check-databases --check-unused-labels --check-repeated-labels --check-redefined-labels --check-use-before-definition --search-path "${{ github.workspace }}/ql/extractor-pack" --consistency-queries ql/ql/consistency-queries ql/ql/test
|
||||
|
||||
34
.github/workflows/swift-integration-tests.yml
vendored
Normal file
34
.github/workflows/swift-integration-tests.yml
vendored
Normal file
@@ -0,0 +1,34 @@
|
||||
name: "Swift: Run Integration Tests"
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
paths:
|
||||
- "swift/**"
|
||||
- .github/workflows/swift-integration-tests.yml
|
||||
- codeql-workspace.yml
|
||||
branches:
|
||||
- main
|
||||
defaults:
|
||||
run:
|
||||
working-directory: swift
|
||||
|
||||
jobs:
|
||||
integration-tests:
|
||||
runs-on: ${{ matrix.os }}
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os:
|
||||
- ubuntu-20.04
|
||||
# - macos-latest TODO
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: ./.github/actions/fetch-codeql
|
||||
- uses: bazelbuild/setup-bazelisk@v2
|
||||
- uses: actions/setup-python@v3
|
||||
- name: Build Swift extractor
|
||||
run: |
|
||||
bazel run //swift:create-extractor-pack
|
||||
- name: Run integration tests
|
||||
run: |
|
||||
python integration-tests/runner.py
|
||||
@@ -42,3 +42,4 @@ WORKSPACE.bazel @github/codeql-ci-reviewers
|
||||
/.github/workflows/js-ml-tests.yml @github/codeql-ml-powered-queries-reviewers
|
||||
/.github/workflows/ql-for-ql-* @github/codeql-ql-for-ql-reviewers
|
||||
/.github/workflows/ruby-* @github/codeql-ruby
|
||||
/.github/workflows/swift-* @github/codeql-c
|
||||
|
||||
@@ -1,3 +1,9 @@
|
||||
## 0.3.1
|
||||
|
||||
### Minor Analysis Improvements
|
||||
|
||||
* `AnalysedExpr::isNullCheck` and `AnalysedExpr::isValidCheck` have been updated to handle variable accesses on the left-hand side of the C++ logical "and", and variable declarations in conditions.
|
||||
|
||||
## 0.3.0
|
||||
|
||||
### Deprecated APIs
|
||||
|
||||
4
cpp/ql/lib/change-notes/2022-06-24-unique-variable.md
Normal file
4
cpp/ql/lib/change-notes/2022-06-24-unique-variable.md
Normal file
@@ -0,0 +1,4 @@
|
||||
---
|
||||
category: fix
|
||||
---
|
||||
* Under certain circumstances a variable declaration that is not also a definition could be associated with a `Variable` that did not have the definition as a `VariableDeclarationEntry`. This is now fixed, and a unique `Variable` will exist that has both the declaration and the definition as a `VariableDeclarationEntry`.
|
||||
5
cpp/ql/lib/change-notes/released/0.3.1.md
Normal file
5
cpp/ql/lib/change-notes/released/0.3.1.md
Normal file
@@ -0,0 +1,5 @@
|
||||
## 0.3.1
|
||||
|
||||
### Minor Analysis Improvements
|
||||
|
||||
* `AnalysedExpr::isNullCheck` and `AnalysedExpr::isValidCheck` have been updated to handle variable accesses on the left-hand side of the C++ logical "and", and variable declarations in conditions.
|
||||
@@ -1,2 +1,2 @@
|
||||
---
|
||||
lastReleaseVersion: 0.3.0
|
||||
lastReleaseVersion: 0.3.1
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
name: codeql/cpp-all
|
||||
version: 0.3.1-dev
|
||||
version: 0.3.2-dev
|
||||
groups: cpp
|
||||
dbscheme: semmlecode.cpp.dbscheme
|
||||
extractor: cpp
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
import semmle.code.cpp.Location
|
||||
private import semmle.code.cpp.Enclosing
|
||||
private import semmle.code.cpp.internal.ResolveClass
|
||||
private import semmle.code.cpp.internal.ResolveGlobalVariable
|
||||
|
||||
/**
|
||||
* Get the `Element` that represents this `@element`.
|
||||
@@ -28,9 +29,12 @@ Element mkElement(@element e) { unresolveElement(result) = e }
|
||||
pragma[inline]
|
||||
@element unresolveElement(Element e) {
|
||||
not result instanceof @usertype and
|
||||
not result instanceof @variable and
|
||||
result = e
|
||||
or
|
||||
e = resolveClass(result)
|
||||
or
|
||||
e = resolveGlobalVariable(result)
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -6,6 +6,7 @@ import semmle.code.cpp.Element
|
||||
import semmle.code.cpp.exprs.Access
|
||||
import semmle.code.cpp.Initializer
|
||||
private import semmle.code.cpp.internal.ResolveClass
|
||||
private import semmle.code.cpp.internal.ResolveGlobalVariable
|
||||
|
||||
/**
|
||||
* A C/C++ variable. For example, in the following code there are four
|
||||
@@ -32,6 +33,8 @@ private import semmle.code.cpp.internal.ResolveClass
|
||||
* can have multiple declarations.
|
||||
*/
|
||||
class Variable extends Declaration, @variable {
|
||||
Variable() { isVariable(underlyingElement(this)) }
|
||||
|
||||
override string getAPrimaryQlClass() { result = "Variable" }
|
||||
|
||||
/** Gets the initializer of this variable, if any. */
|
||||
|
||||
@@ -46,7 +46,7 @@ predicate nullCheckExpr(Expr checkExpr, Variable var) {
|
||||
or
|
||||
exists(LogicalAndExpr op, AnalysedExpr child |
|
||||
expr = op and
|
||||
op.getRightOperand() = child and
|
||||
op.getAnOperand() = child and
|
||||
nullCheckExpr(child, v)
|
||||
)
|
||||
or
|
||||
@@ -99,7 +99,7 @@ predicate validCheckExpr(Expr checkExpr, Variable var) {
|
||||
or
|
||||
exists(LogicalAndExpr op, AnalysedExpr child |
|
||||
expr = op and
|
||||
op.getRightOperand() = child and
|
||||
op.getAnOperand() = child and
|
||||
validCheckExpr(child, v)
|
||||
)
|
||||
or
|
||||
@@ -169,7 +169,10 @@ class AnalysedExpr extends Expr {
|
||||
*/
|
||||
predicate isDef(LocalScopeVariable v) {
|
||||
this.inCondition() and
|
||||
this.(Assignment).getLValue() = v.getAnAccess()
|
||||
(
|
||||
this.(Assignment).getLValue() = v.getAnAccess() or
|
||||
this.(ConditionDeclExpr).getVariableAccess() = v.getAnAccess()
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -255,8 +255,10 @@ class FunctionCall extends Call, @funbindexpr {
|
||||
/**
|
||||
* Gets the function called by this call.
|
||||
*
|
||||
* In the case of virtual function calls, the result is the most-specific function in the override tree (as
|
||||
* determined by the compiler) such that the target at runtime will be one of `result.getAnOverridingFunction*()`.
|
||||
* In the case of virtual function calls, the result is the most-specific function in the override tree
|
||||
* such that the target at runtime will be one of `result.getAnOverridingFunction*()`. The most-specific
|
||||
* function is determined by the compiler based on the compile time type of the object the function is a
|
||||
* member of.
|
||||
*/
|
||||
override Function getTarget() { funbind(underlyingElement(this), unresolveElement(result)) }
|
||||
|
||||
|
||||
@@ -0,0 +1,57 @@
|
||||
private predicate hasDefinition(@globalvariable g) {
|
||||
exists(@var_decl vd | var_decls(vd, g, _, _, _) | var_def(vd))
|
||||
}
|
||||
|
||||
private predicate onlyOneCompleteGlobalVariableExistsWithMangledName(@mangledname name) {
|
||||
strictcount(@globalvariable g | hasDefinition(g) and mangled_name(g, name)) = 1
|
||||
}
|
||||
|
||||
/** Holds if `g` is a unique global variable with a definition named `name`. */
|
||||
private predicate isGlobalWithMangledNameAndWithDefinition(@mangledname name, @globalvariable g) {
|
||||
hasDefinition(g) and
|
||||
mangled_name(g, name) and
|
||||
onlyOneCompleteGlobalVariableExistsWithMangledName(name)
|
||||
}
|
||||
|
||||
/** Holds if `g` is a global variable without a definition named `name`. */
|
||||
private predicate isGlobalWithMangledNameAndWithoutDefinition(@mangledname name, @globalvariable g) {
|
||||
not hasDefinition(g) and
|
||||
mangled_name(g, name)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if `incomplete` is a global variable without a definition, and there exists
|
||||
* a unique global variable `complete` with the same name that does have a definition.
|
||||
*/
|
||||
private predicate hasTwinWithDefinition(@globalvariable incomplete, @globalvariable complete) {
|
||||
exists(@mangledname name |
|
||||
not variable_instantiation(incomplete, complete) and
|
||||
isGlobalWithMangledNameAndWithoutDefinition(name, incomplete) and
|
||||
isGlobalWithMangledNameAndWithDefinition(name, complete)
|
||||
)
|
||||
}
|
||||
|
||||
import Cached
|
||||
|
||||
cached
|
||||
private module Cached {
|
||||
/**
|
||||
* If `v` is a global variable without a definition, and there exists a unique
|
||||
* global variable with the same name that does have a definition, then the
|
||||
* result is that unique global variable. Otherwise, the result is `v`.
|
||||
*/
|
||||
cached
|
||||
@variable resolveGlobalVariable(@variable v) {
|
||||
hasTwinWithDefinition(v, result)
|
||||
or
|
||||
not hasTwinWithDefinition(v, _) and
|
||||
result = v
|
||||
}
|
||||
|
||||
cached
|
||||
predicate isVariable(@variable v) {
|
||||
not v instanceof @globalvariable
|
||||
or
|
||||
v = resolveGlobalVariable(_)
|
||||
}
|
||||
}
|
||||
@@ -1,3 +1,9 @@
|
||||
## 0.3.0
|
||||
|
||||
### Breaking Changes
|
||||
|
||||
* Contextual queries and the query libraries they depend on have been moved to the `codeql/cpp-all` package.
|
||||
|
||||
## 0.2.0
|
||||
|
||||
## 0.1.4
|
||||
|
||||
@@ -44,7 +44,7 @@ predicate whiteListWrapped(FunctionCall fc) {
|
||||
|
||||
from FunctionCall c, FloatingPointType t1, IntegralType t2
|
||||
where
|
||||
t1 = c.getTarget().getType().getUnderlyingType() and
|
||||
pragma[only_bind_into](t1) = c.getTarget().getType().getUnderlyingType() and
|
||||
t2 = c.getActualType() and
|
||||
c.hasImplicitConversion() and
|
||||
not whiteListWrapped(c)
|
||||
|
||||
@@ -18,7 +18,7 @@ import semmle.code.cpp.ir.IR
|
||||
import semmle.code.cpp.ir.dataflow.MustFlow
|
||||
import PathGraph
|
||||
|
||||
/** Holds if `f` has a name that we intrepret as evidence of intentionally returning the value of the stack pointer. */
|
||||
/** Holds if `f` has a name that we interpret as evidence of intentionally returning the value of the stack pointer. */
|
||||
predicate intentionallyReturnsStackPointer(Function f) {
|
||||
f.getName().toLowerCase().matches(["%stack%", "%sp%"])
|
||||
}
|
||||
@@ -74,13 +74,12 @@ class ReturnStackAllocatedMemoryConfig extends MustFlowConfiguration {
|
||||
|
||||
from
|
||||
MustFlowPathNode source, MustFlowPathNode sink, VariableAddressInstruction var,
|
||||
ReturnStackAllocatedMemoryConfig conf, Function f
|
||||
ReturnStackAllocatedMemoryConfig conf
|
||||
where
|
||||
conf.hasFlowPath(source, sink) and
|
||||
conf.hasFlowPath(pragma[only_bind_into](source), pragma[only_bind_into](sink)) and
|
||||
source.getNode().asInstruction() = var and
|
||||
// Only raise an alert if we're returning from the _same_ callable as the on that
|
||||
// declared the stack variable.
|
||||
var.getEnclosingFunction() = pragma[only_bind_into](f) and
|
||||
sink.getNode().getEnclosingCallable() = pragma[only_bind_into](f)
|
||||
var.getEnclosingFunction() = sink.getNode().getEnclosingCallable()
|
||||
select sink.getNode(), source, sink, "May return stack-allocated memory from $@.", var.getAst(),
|
||||
var.getAst().toString()
|
||||
|
||||
@@ -15,6 +15,7 @@ class VariableAccessInInitializer extends VariableAccess {
|
||||
Variable var;
|
||||
Initializer init;
|
||||
|
||||
pragma[nomagic]
|
||||
VariableAccessInInitializer() {
|
||||
init.getDeclaration() = var and
|
||||
init.getExpr().getAChild*() = this
|
||||
|
||||
@@ -77,7 +77,7 @@ class ExecState extends DataFlow::FlowState {
|
||||
ExecState() {
|
||||
this =
|
||||
"ExecState (" + fst.getLocation() + " | " + fst + ", " + snd.getLocation() + " | " + snd + ")" and
|
||||
interestingConcatenation(fst, snd)
|
||||
interestingConcatenation(pragma[only_bind_into](fst), pragma[only_bind_into](snd))
|
||||
}
|
||||
|
||||
DataFlow::Node getFstNode() { result = fst }
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
---
|
||||
category: breaking
|
||||
---
|
||||
## 0.3.0
|
||||
|
||||
### Breaking Changes
|
||||
|
||||
* Contextual queries and the query libraries they depend on have been moved to the `codeql/cpp-all` package.
|
||||
@@ -1,2 +1,2 @@
|
||||
---
|
||||
lastReleaseVersion: 0.2.0
|
||||
lastReleaseVersion: 0.3.0
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
name: codeql/cpp-queries
|
||||
version: 0.2.1-dev
|
||||
version: 0.3.1-dev
|
||||
groups:
|
||||
- cpp
|
||||
- queries
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
| test.cpp:9:9:9:9 | v | test.cpp:5:13:5:13 | v | is not null | is valid |
|
||||
| test.cpp:10:9:10:10 | ! ... | test.cpp:5:13:5:13 | v | is null | is not valid |
|
||||
| test.cpp:11:9:11:14 | ... == ... | test.cpp:5:13:5:13 | v | is null | is not valid |
|
||||
| test.cpp:12:9:12:17 | ... == ... | test.cpp:5:13:5:13 | v | is not null | is valid |
|
||||
| test.cpp:13:9:13:14 | ... != ... | test.cpp:5:13:5:13 | v | is not null | is valid |
|
||||
| test.cpp:14:9:14:17 | ... != ... | test.cpp:5:13:5:13 | v | is null | is not valid |
|
||||
| test.cpp:15:8:15:23 | call to __builtin_expect | test.cpp:5:13:5:13 | v | is not null | is valid |
|
||||
| test.cpp:16:8:16:23 | call to __builtin_expect | test.cpp:5:13:5:13 | v | is null | is not valid |
|
||||
| test.cpp:17:9:17:17 | ... && ... | test.cpp:5:13:5:13 | v | is not null | is valid |
|
||||
| test.cpp:18:9:18:17 | ... && ... | test.cpp:5:13:5:13 | v | is not null | is valid |
|
||||
| test.cpp:19:9:19:18 | ... && ... | test.cpp:5:13:5:13 | v | is null | is not valid |
|
||||
| test.cpp:20:9:20:18 | ... && ... | test.cpp:5:13:5:13 | v | is null | is not valid |
|
||||
| test.cpp:21:9:21:14 | ... = ... | test.cpp:5:13:5:13 | v | is null | is not valid |
|
||||
| test.cpp:21:9:21:14 | ... = ... | test.cpp:7:10:7:10 | b | is not null | is valid |
|
||||
| test.cpp:22:9:22:14 | ... = ... | test.cpp:5:13:5:13 | v | is not null | is not valid |
|
||||
| test.cpp:22:9:22:14 | ... = ... | test.cpp:7:13:7:13 | c | is not null | is not valid |
|
||||
| test.cpp:22:17:22:17 | c | test.cpp:7:13:7:13 | c | is not null | is valid |
|
||||
| test.cpp:23:21:23:21 | x | test.cpp:23:14:23:14 | x | is not null | is valid |
|
||||
| test.cpp:24:9:24:18 | (condition decl) | test.cpp:5:13:5:13 | v | is not null | is not valid |
|
||||
| test.cpp:24:9:24:18 | (condition decl) | test.cpp:24:14:24:14 | y | is not null | is valid |
|
||||
@@ -0,0 +1,8 @@
|
||||
import cpp
|
||||
|
||||
from AnalysedExpr a, LocalScopeVariable v, string isNullCheck, string isValidCheck
|
||||
where
|
||||
v.getAnAccess().getEnclosingStmt() = a.getParent() and
|
||||
(if a.isNullCheck(v) then isNullCheck = "is null" else isNullCheck = "is not null") and
|
||||
(if a.isValidCheck(v) then isValidCheck = "is valid" else isValidCheck = "is not valid")
|
||||
select a, v, isNullCheck, isValidCheck
|
||||
25
cpp/ql/test/library-tests/controlflow/nullness/test.cpp
Normal file
25
cpp/ql/test/library-tests/controlflow/nullness/test.cpp
Normal file
@@ -0,0 +1,25 @@
|
||||
// semmle-extractor-options: -std=c++17
|
||||
|
||||
long __builtin_expect(long);
|
||||
|
||||
void f(int *v) {
|
||||
int *w;
|
||||
bool b, c;
|
||||
|
||||
if (v) {}
|
||||
if (!v) {}
|
||||
if (v == 0) {}
|
||||
if ((!v) == 0) {}
|
||||
if (v != 0) {}
|
||||
if ((!v) != 0) {}
|
||||
if(__builtin_expect((long)v)) {}
|
||||
if(__builtin_expect((long)!v)) {}
|
||||
if (true && v) {}
|
||||
if (v && true) {}
|
||||
if (true && !v) {}
|
||||
if (!v && true) {}
|
||||
if (b = !v) {}
|
||||
if (c = !v; c) {}
|
||||
if (int *x = v; x) {}
|
||||
if (int *y = v) {}
|
||||
}
|
||||
@@ -4,11 +4,7 @@
|
||||
| c.c:6:5:6:6 | ls | array of 4 {int} | 1 |
|
||||
| c.c:8:5:8:7 | iss | array of 4 {array of 2 {int}} | 1 |
|
||||
| c.c:12:11:12:11 | i | typedef {int} as "int_alias" | 1 |
|
||||
| c.h:4:12:4:13 | ks | array of {int} | 1 |
|
||||
| c.h:8:12:8:14 | iss | array of {array of 2 {int}} | 1 |
|
||||
| c.h:10:12:10:12 | i | int | 1 |
|
||||
| d.cpp:3:7:3:8 | xs | array of {int} | 1 |
|
||||
| d.h:3:14:3:15 | xs | array of 2 {int} | 1 |
|
||||
| file://:0:0:0:0 | (unnamed parameter 0) | reference to {const {struct __va_list_tag}} | 1 |
|
||||
| file://:0:0:0:0 | (unnamed parameter 0) | rvalue reference to {struct __va_list_tag} | 1 |
|
||||
| file://:0:0:0:0 | fp_offset | unsigned int | 1 |
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
## 1.2.1
|
||||
|
||||
## 1.2.0
|
||||
|
||||
## 1.1.4
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
## 1.2.1
|
||||
@@ -1,2 +1,2 @@
|
||||
---
|
||||
lastReleaseVersion: 1.2.0
|
||||
lastReleaseVersion: 1.2.1
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
name: codeql/csharp-solorigate-all
|
||||
version: 1.2.1-dev
|
||||
version: 1.2.2-dev
|
||||
groups:
|
||||
- csharp
|
||||
- solorigate
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
## 1.2.1
|
||||
|
||||
## 1.2.0
|
||||
|
||||
## 1.1.4
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
## 1.2.1
|
||||
@@ -1,2 +1,2 @@
|
||||
---
|
||||
lastReleaseVersion: 1.2.0
|
||||
lastReleaseVersion: 1.2.1
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
name: codeql/csharp-solorigate-queries
|
||||
version: 1.2.1-dev
|
||||
version: 1.2.2-dev
|
||||
groups:
|
||||
- csharp
|
||||
- solorigate
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
## 0.3.1
|
||||
|
||||
## 0.3.0
|
||||
|
||||
### Deprecated APIs
|
||||
|
||||
1
csharp/ql/lib/change-notes/released/0.3.1.md
Normal file
1
csharp/ql/lib/change-notes/released/0.3.1.md
Normal file
@@ -0,0 +1 @@
|
||||
## 0.3.1
|
||||
@@ -1,2 +1,2 @@
|
||||
---
|
||||
lastReleaseVersion: 0.3.0
|
||||
lastReleaseVersion: 0.3.1
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
name: codeql/csharp-all
|
||||
version: 0.3.1-dev
|
||||
version: 0.3.2-dev
|
||||
groups: csharp
|
||||
dbscheme: semmlecode.csharp.dbscheme
|
||||
extractor: csharp
|
||||
|
||||
@@ -1,3 +1,9 @@
|
||||
## 0.3.0
|
||||
|
||||
### Breaking Changes
|
||||
|
||||
* Contextual queries and the query libraries they depend on have been moved to the `codeql/csharp-all` package.
|
||||
|
||||
## 0.2.0
|
||||
|
||||
### Query Metadata Changes
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
---
|
||||
category: breaking
|
||||
---
|
||||
## 0.3.0
|
||||
|
||||
### Breaking Changes
|
||||
|
||||
* Contextual queries and the query libraries they depend on have been moved to the `codeql/csharp-all` package.
|
||||
@@ -1,2 +1,2 @@
|
||||
---
|
||||
lastReleaseVersion: 0.2.0
|
||||
lastReleaseVersion: 0.3.0
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
|
||||
{
|
||||
SymmetricKey aesKey = new SymmetricKey(kid: "symencryptionkey");
|
||||
|
||||
// BAD: Using the outdated client side encryption version V1_0
|
||||
BlobEncryptionPolicy uploadPolicy = new BlobEncryptionPolicy(key: aesKey, keyResolver: null);
|
||||
BlobRequestOptions uploadOptions = new BlobRequestOptions() { EncryptionPolicy = uploadPolicy };
|
||||
|
||||
MemoryStream stream = new MemoryStream(buffer);
|
||||
blob.UploadFromStream(stream, length: size, accessCondition: null, options: uploadOptions);
|
||||
}
|
||||
|
||||
var client = new BlobClient(myConnectionString, new SpecializedBlobClientOptions()
|
||||
{
|
||||
// BAD: Using an outdated SDK that does not support client side encryption version V2_0
|
||||
ClientSideEncryption = new ClientSideEncryptionOptions()
|
||||
{
|
||||
KeyEncryptionKey = myKey,
|
||||
KeyResolver = myKeyResolver,
|
||||
KeyWrapAlgorihm = myKeyWrapAlgorithm
|
||||
}
|
||||
});
|
||||
|
||||
var client = new BlobClient(myConnectionString, new SpecializedBlobClientOptions()
|
||||
{
|
||||
// BAD: Using the outdated client side encryption version V1_0
|
||||
ClientSideEncryption = new ClientSideEncryptionOptions(ClientSideEncryptionVersion.V1_0)
|
||||
{
|
||||
KeyEncryptionKey = myKey,
|
||||
KeyResolver = myKeyResolver,
|
||||
KeyWrapAlgorihm = myKeyWrapAlgorithm
|
||||
}
|
||||
});
|
||||
|
||||
var client = new BlobClient(myConnectionString, new SpecializedBlobClientOptions()
|
||||
{
|
||||
// GOOD: Using client side encryption version V2_0
|
||||
ClientSideEncryption = new ClientSideEncryptionOptions(ClientSideEncryptionVersion.V2_0)
|
||||
{
|
||||
KeyEncryptionKey = myKey,
|
||||
KeyResolver = myKeyResolver,
|
||||
KeyWrapAlgorihm = myKeyWrapAlgorithm
|
||||
}
|
||||
});
|
||||
@@ -0,0 +1,29 @@
|
||||
<!DOCTYPE qhelp PUBLIC "-//Semmle//qhelp//EN" "qhelp.dtd">
|
||||
<qhelp>
|
||||
|
||||
|
||||
<overview>
|
||||
<p>Azure Storage .NET, Java, and Python SDKs support encryption on the client with a customer-managed key that is maintained in Azure Key Vault or another key store.</p>
|
||||
<p>Current release versions of the Azure Storage SDKs use cipher block chaining (CBC mode) for client-side encryption (referred to as <code>v1</code>).</p>
|
||||
|
||||
</overview>
|
||||
<recommendation>
|
||||
|
||||
<p>Consider switching to <code>v2</code> client-side encryption.</p>
|
||||
|
||||
</recommendation>
|
||||
<example>
|
||||
|
||||
<sample src="UnsafeUsageOfClientSideEncryptionVersion.cs" />
|
||||
|
||||
</example>
|
||||
<references>
|
||||
<li>
|
||||
<a href="http://aka.ms/azstorageclientencryptionblog">Azure Storage Client Encryption Blog.</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-30187">CVE-2022-30187</a>
|
||||
</li>
|
||||
|
||||
</references>
|
||||
</qhelp>
|
||||
@@ -0,0 +1,81 @@
|
||||
/**
|
||||
* @name Unsafe usage of v1 version of Azure Storage client-side encryption (CVE-2022-30187).
|
||||
* @description Unsafe usage of v1 version of Azure Storage client-side encryption, please refer to http://aka.ms/azstorageclientencryptionblog
|
||||
* @kind problem
|
||||
* @tags security
|
||||
* cryptography
|
||||
* external/cwe/cwe-327
|
||||
* @id cs/azure-storage/unsafe-usage-of-client-side-encryption-version
|
||||
* @problem.severity error
|
||||
* @precision high
|
||||
*/
|
||||
|
||||
import csharp
|
||||
|
||||
/**
|
||||
* Holds if `oc` is creating an object of type `c` = `Azure.Storage.ClientSideEncryptionOptions`
|
||||
* and `e` is the `version` argument to the constructor
|
||||
*/
|
||||
predicate isCreatingAzureClientSideEncryptionObject(ObjectCreation oc, Class c, Expr e) {
|
||||
exists(Parameter p | p.hasName("version") |
|
||||
c.hasQualifiedName("Azure.Storage.ClientSideEncryptionOptions") and
|
||||
oc.getTarget() = c.getAConstructor() and
|
||||
e = oc.getArgumentForParameter(p)
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if `oc` is an object creation of the outdated type `c` = `Microsoft.Azure.Storage.Blob.BlobEncryptionPolicy`
|
||||
*/
|
||||
predicate isCreatingOutdatedAzureClientSideEncryptionObject(ObjectCreation oc, Class c) {
|
||||
c.hasQualifiedName("Microsoft.Azure.Storage.Blob.BlobEncryptionPolicy") and
|
||||
oc.getTarget() = c.getAConstructor()
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if the Azure.Storage assembly for `c` is a version known to support
|
||||
* version 2+ for client-side encryption
|
||||
*/
|
||||
predicate doesAzureStorageAssemblySupportSafeClientSideEncryption(Assembly asm) {
|
||||
exists(int versionCompare |
|
||||
versionCompare = asm.getVersion().compareTo("12.12.0.0") and
|
||||
versionCompare >= 0
|
||||
) and
|
||||
asm.getName() = "Azure.Storage.Common"
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if the Azure.Storage assembly for `c` is a version known to support
|
||||
* version 2+ for client-side encryption and if the argument for the constructor `version`
|
||||
* is set to a secure value.
|
||||
*/
|
||||
predicate isObjectCreationArgumentSafeAndUsingSafeVersionOfAssembly(Expr versionExpr, Assembly asm) {
|
||||
// Check if the Azure.Storage assembly version has the fix
|
||||
doesAzureStorageAssemblySupportSafeClientSideEncryption(asm) and
|
||||
// and that the version argument for the constructor is guaranteed to be Version2
|
||||
isExprAnAccessToSafeClientSideEncryptionVersionValue(versionExpr)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if the expression `e` is an access to a safe version of the enum `ClientSideEncryptionVersion`
|
||||
* or an equivalent numeric value
|
||||
*/
|
||||
predicate isExprAnAccessToSafeClientSideEncryptionVersionValue(Expr e) {
|
||||
exists(EnumConstant ec |
|
||||
ec.hasQualifiedName("Azure.Storage.ClientSideEncryptionVersion.V2_0") and
|
||||
ec.getAnAccess() = e
|
||||
)
|
||||
}
|
||||
|
||||
from Expr e, Class c, Assembly asm
|
||||
where
|
||||
asm = c.getLocation() and
|
||||
(
|
||||
exists(Expr e2 |
|
||||
isCreatingAzureClientSideEncryptionObject(e, c, e2) and
|
||||
not isObjectCreationArgumentSafeAndUsingSafeVersionOfAssembly(e2, asm)
|
||||
)
|
||||
or
|
||||
isCreatingOutdatedAzureClientSideEncryptionObject(e, c)
|
||||
)
|
||||
select e, "Unsafe usage of v1 version of Azure Storage client-side encryption."
|
||||
@@ -1,5 +1,5 @@
|
||||
name: codeql/csharp-queries
|
||||
version: 0.2.1-dev
|
||||
version: 0.3.1-dev
|
||||
groups:
|
||||
- csharp
|
||||
- queries
|
||||
|
||||
@@ -2,7 +2,54 @@ function RegisterExtractorPack(id)
|
||||
local extractor = GetPlatformToolsDirectory() ..
|
||||
'Semmle.Extraction.CSharp.Driver'
|
||||
if OperatingSystem == 'windows' then extractor = extractor .. '.exe' end
|
||||
|
||||
function DotnetMatcherBuild(compilerName, compilerPath, compilerArguments,
|
||||
_languageId)
|
||||
if compilerName ~= 'dotnet' and compilerName ~= 'dotnet.exe' then
|
||||
return nil
|
||||
end
|
||||
|
||||
-- The dotnet CLI has the following usage instructions:
|
||||
-- dotnet [sdk-options] [command] [command-options] [arguments]
|
||||
-- we are interested in dotnet build, which has the following usage instructions:
|
||||
-- dotnet [options] build [<PROJECT | SOLUTION>...]
|
||||
-- For now, parse the command line as follows:
|
||||
-- Everything that starts with `-` (or `/`) will be ignored.
|
||||
-- The first non-option argument is treated as the command.
|
||||
-- if that's `build`, we append `/p:UseSharedCompilation=false` to the command line,
|
||||
-- otherwise we do nothing.
|
||||
local match = false
|
||||
local argv = compilerArguments.argv
|
||||
if OperatingSystem == 'windows' then
|
||||
-- let's hope that this split matches the escaping rules `dotnet` applies to command line arguments
|
||||
-- or, at least, that it is close enough
|
||||
argv =
|
||||
NativeArgumentsToArgv(compilerArguments.nativeArgumentPointer)
|
||||
end
|
||||
for i, arg in ipairs(argv) do
|
||||
-- dotnet options start with either - or / (both are legal)
|
||||
local firstCharacter = string.sub(arg, 1, 1)
|
||||
if not (firstCharacter == '-') and not (firstCharacter == '/') then
|
||||
Log(1, 'Dotnet subcommand detected: %s', arg)
|
||||
if arg == 'build' then match = true end
|
||||
break
|
||||
end
|
||||
end
|
||||
if match then
|
||||
return {
|
||||
order = ORDER_REPLACE,
|
||||
invocation = BuildExtractorInvocation(id, compilerPath,
|
||||
compilerPath,
|
||||
compilerArguments, nil, {
|
||||
'/p:UseSharedCompilation=false'
|
||||
})
|
||||
}
|
||||
end
|
||||
return nil
|
||||
end
|
||||
|
||||
local windowsMatchers = {
|
||||
DotnetMatcherBuild,
|
||||
CreatePatternMatcher({'^dotnet%.exe$'}, MatchCompilerName, extractor, {
|
||||
prepend = {'--dotnetexec', '--cil'},
|
||||
order = ORDER_BEFORE
|
||||
@@ -10,22 +57,21 @@ function RegisterExtractorPack(id)
|
||||
CreatePatternMatcher({'^csc.*%.exe$'}, MatchCompilerName, extractor, {
|
||||
prepend = {'--compiler', '"${compiler}"', '--cil'},
|
||||
order = ORDER_BEFORE
|
||||
|
||||
}),
|
||||
CreatePatternMatcher({'^fakes.*%.exe$', 'moles.*%.exe'},
|
||||
MatchCompilerName, nil, {trace = false})
|
||||
}
|
||||
local posixMatchers = {
|
||||
CreatePatternMatcher({'^mcs%.exe$', '^csc%.exe$'}, MatchCompilerName,
|
||||
extractor, {
|
||||
prepend = {'--compiler', '"${compiler}"', '--cil'},
|
||||
order = ORDER_BEFORE
|
||||
|
||||
}),
|
||||
DotnetMatcherBuild,
|
||||
CreatePatternMatcher({'^mono', '^dotnet$'}, MatchCompilerName,
|
||||
extractor, {
|
||||
prepend = {'--dotnetexec', '--cil'},
|
||||
order = ORDER_BEFORE
|
||||
}),
|
||||
CreatePatternMatcher({'^mcs%.exe$', '^csc%.exe$'}, MatchCompilerName,
|
||||
extractor, {
|
||||
prepend = {'--compiler', '"${compiler}"', '--cil'},
|
||||
order = ORDER_BEFORE
|
||||
}), function(compilerName, compilerPath, compilerArguments, _languageId)
|
||||
if MatchCompilerName('^msbuild$', compilerName, compilerPath,
|
||||
compilerArguments) or
|
||||
@@ -49,7 +95,6 @@ function RegisterExtractorPack(id)
|
||||
else
|
||||
return posixMatchers
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
-- Return a list of minimum supported versions of the configuration file format
|
||||
|
||||
@@ -135,6 +135,47 @@ pack names and use the ``--download`` flag::
|
||||
The ``analyze`` command above runs the default suite from ``microsoft/coding-standards v1.0.0`` and the latest version of ``github/security-queries`` on the specified database.
|
||||
For further information about default suites, see ":ref:`Publishing and using CodeQL packs <publishing-and-using-codeql-packs>`".
|
||||
|
||||
Running a subset of queries in a CodeQL pack
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
If you are using CodeQL CLI v2.8.1 or later, you can include a path at the end of a pack specification to run a subset of queries inside the pack. This applies to any command that locates or runs queries within a pack.
|
||||
|
||||
The complete way to specify a set of queries is in the form ``scope/name@range:path``, where:
|
||||
|
||||
- ``scope/name`` is the qualified name of a CodeQL pack.
|
||||
- ``range`` is a `semver range <https://docs.npmjs.com/cli/v6/using-npm/semver#ranges>`_.
|
||||
- ``path`` is a file system path to a single query, a directory containing queries, or a query suite file.
|
||||
|
||||
When you specify a ``scope/name``, the ``range`` and ``path`` are
|
||||
optional. If you omit a ``range`` then the latest version of the
|
||||
specified pack is used. If you omit a ``path`` then the default query suite
|
||||
of the specified pack is used.
|
||||
|
||||
The ``path`` can be one of a ``*.ql`` query file, a directory
|
||||
containing one or more queries, or a ``.qls`` query suite file. If
|
||||
you omit a pack name, then you must provide a ``path``,
|
||||
which will be interpreted relative to the working directory
|
||||
of the current process.
|
||||
|
||||
If you specify a ``scope/name`` and ``path``, then the ``path`` cannot
|
||||
be absolute. It is considered relative to the root of the CodeQL
|
||||
pack.
|
||||
|
||||
To analyze a database using all queries in the `experimental/Security` folder within the `codeql/cpp-queries` CodeQL pack you can use::
|
||||
|
||||
codeql database analyze --format=sarif-latest --output=results <db> \
|
||||
codeql/cpp-queries:experimental/Security
|
||||
|
||||
To run the `RedundantNullCheckParam.ql` query in the `codeql/cpp-queries` CodeQL pack use::
|
||||
|
||||
codeql database analyze --format=sarif-latest --output=results <db> \
|
||||
'codeql/cpp-queries:experimental/Likely Bugs/RedundantNullCheckParam.ql'
|
||||
|
||||
To analyze your database using the `cpp-security-and-quality.qls` query suite from a version of the `codeql/cpp-queries` CodeQL pack that is >= 0.0.3 and < 0.1.0 (the highest compatible version will be chosen) you can use::
|
||||
|
||||
codeql database analyze --format=sarif-latest --output=results <db> \
|
||||
'codeql/cpp-queries@~0.0.3:codeql-suites/cpp-security-and-quality.qls'
|
||||
|
||||
For more information about CodeQL packs, see :doc:`About CodeQL Packs <about-codeql-packs>`.
|
||||
|
||||
Running query suites
|
||||
@@ -223,7 +264,7 @@ you can include the query help for your custom queries in SARIF files generated
|
||||
After uploading the SARIF file to GitHub, the query help is shown in the code scanning UI for any
|
||||
alerts generated by the custom queries.
|
||||
|
||||
From CodeQL CLI 2.7.1 onwards, you can include markdown-rendered query help in SARIF files
|
||||
From CodeQL CLI v2.7.1 onwards, you can include markdown-rendered query help in SARIF files
|
||||
by providing the ``--sarif-add-query-help`` option when running
|
||||
``codeql database analyze``.
|
||||
For more information, see `Configuring CodeQL CLI in your CI system <https://docs.github.com/en/code-security/code-scanning/using-codeql-code-scanning-with-your-existing-ci-system/configuring-codeql-cli-in-your-ci-system#analyzing-a-codeql-database>`__
|
||||
|
||||
@@ -68,3 +68,11 @@ This command downloads all dependencies to the shared cache on the local disk.
|
||||
Note
|
||||
|
||||
Running the ``codeql pack add`` and ``codeql pack install`` commands will generate or update the ``qlpack.lock.yml`` file. This file should be checked-in to version control. The ``qlpack.lock.yml`` file contains the precise version numbers used by the pack.
|
||||
|
||||
.. pull-quote::
|
||||
|
||||
Note
|
||||
|
||||
By default ``codeql pack install`` will install dependencies from the Container registry on GitHub.com.
|
||||
You can install dependencies from a GitHub Enterprise Server Container registry by creating a ``qlconfig.yml`` file.
|
||||
For more information, see ":doc:`Publishing and using CodeQL packs <publishing-and-using-codeql-packs>`."
|
||||
|
||||
@@ -72,3 +72,53 @@ The ``analyze`` command will run the default suite of any specified CodeQL packs
|
||||
::
|
||||
|
||||
codeql <database> analyze <scope>/<pack> <scope>/<other-pack>
|
||||
|
||||
Working with CodeQL packs on GitHub Enterprise Server
|
||||
-----------------------------------------------------
|
||||
|
||||
.. pull-quote::
|
||||
|
||||
Note
|
||||
|
||||
The Container registry for GitHub Enterprise Server supports CodeQL query packs from GitHub Enterprise Server 3.6 onward.
|
||||
|
||||
By default, the CodeQL CLI expects to download CodeQL packs from and publish packs to the Container registry on GitHub.com. However, you can also work with CodeQL packs in a Container registry on GitHub Enterprise Server 3.6, and later, by creating a ``qlconfig.yml`` file to tell the CLI which Container registry to use for each pack.
|
||||
|
||||
Create a ``~/.codeql/qlconfig.yml`` file using your preferred text editor, and add entries to specify which registry to use for one or more package name patterns.
|
||||
For example, the following ``qlconfig.yml`` file associates all packs with the Container registry for the GitHub Enterprise Server at ``GHE_HOSTNAME``, except packs matching ``codeql/*``, which are associated with the Container registry on GitHub.com:
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
registries:
|
||||
- packages: 'codeql/*'
|
||||
url: https://ghcr.io/v2/
|
||||
- packages: '*'
|
||||
url: https://containers.GHE_HOSTNAME/v2/
|
||||
|
||||
The CodeQL CLI will determine which registry to use for a given package name by finding the first item in the ``registries`` list with a ``packages`` property that matches that package name.
|
||||
This means that you'll generally want to define the most specific package name patterns first.
|
||||
|
||||
You can now use ``codeql pack publish``, ``codeql pack download``, and ``codeql database analyze`` to manage packs on GitHub Enterprise Server.
|
||||
|
||||
Authenticating to GitHub Container registries
|
||||
---------------------------------------------
|
||||
|
||||
You can publish packs and download private packs by authenticating to the appropriate GitHub Container registry.
|
||||
|
||||
You can authenticate to the Container registry on GitHub.com in two ways:
|
||||
|
||||
1. Pass the ``--github-auth-stdin`` option to the CodeQL CLI, then supply a GitHub Apps token or personal access token via standard input.
|
||||
2. Set the ``GITHUB_TOKEN`` environment variable to a GitHub Apps token or personal access token.
|
||||
|
||||
Similarly, you can authenticate to a GHES Container registry, or authenticate to multiple registries simultaneously (for example, to download or run private packs from multiple registries) in two ways:
|
||||
|
||||
1. Pass the ``--registries-auth-stdin`` option to the CodeQL CLI, then supply a registry authentication string via standard input.
|
||||
2. Set the ``CODEQL_REGISTRIES_AUTH`` environment variable to a registry authentication string.
|
||||
|
||||
A registry authentication string is a comma-separated list of ``<registry-url>=<token>`` pairs, where ``registry-url`` is a GitHub Container registry URL, such as ``https://containers.GHE_HOSTNAME/v2/``, and ``token`` is a GitHub Apps token or personal access token for that GitHub Container registry.
|
||||
This ensures that each token is only passed to the Container registry you specify.
|
||||
For instance, the following registry authentication string specifies that the CodeQL CLI should authenticate to the Container registry on GitHub.com using the token ``<token1>`` and to the Container registry for the GHES instance at ``GHE_HOSTNAME`` using the token ``<token2>``:
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
https://ghcr.io/v2/=<token1>,https://containers.GHE_HOSTNAME/v2/=<token2>
|
||||
|
||||
@@ -11,14 +11,17 @@ CodeQL.
|
||||
Languages and compilers
|
||||
#######################
|
||||
|
||||
CodeQL supports the following languages and compilers.
|
||||
The current versions of the CodeQL CLI (`changelog <https://github.com/github/codeql-cli-binaries/blob/main/CHANGELOG.md>`__, `releases <https://github.com/github/codeql-cli-binaries/releases>`__),
|
||||
CodeQL library packs (`source <https://github.com/github/codeql/tree/codeql-cli/latest>`__),
|
||||
and CodeQL bundle (`releases <https://github.com/github/codeql-action/releases>`__)
|
||||
support the following languages and compilers.
|
||||
|
||||
.. include:: ../support/reusables/versions-compilers.rst
|
||||
|
||||
Frameworks and libraries
|
||||
########################
|
||||
|
||||
The libraries and queries in the current version of CodeQL have been explicitly checked against the libraries and frameworks listed below.
|
||||
The current versions of the CodeQL library and query packs (`source <https://github.com/github/codeql/tree/codeql-cli/latest>`__) have been explicitly checked against the libraries and frameworks listed below.
|
||||
|
||||
.. pull-quote::
|
||||
|
||||
|
||||
@@ -3,7 +3,9 @@ CodeQL query help for C and C++
|
||||
|
||||
.. include:: ../reusables/query-help-overview.rst
|
||||
|
||||
For shorter queries that you can use as building blocks when writing your own queries, see the `example queries in the CodeQL repository <https://github.com/github/codeql/tree/main/cpp/ql/examples>`__.
|
||||
These queries are published in the CodeQL query pack ``codeql/cpp-queries`` (`changelog <https://github.com/github/codeql/tree/codeql-cli/latest/cpp/ql/src/CHANGELOG.md>`__, `source <https://github.com/github/codeql/tree/codeql-cli/latest/cpp/ql/src>`__).
|
||||
|
||||
For shorter queries that you can use as building blocks when writing your own queries, see the `example queries in the CodeQL repository <https://github.com/github/codeql/tree/codeql-cli/latest/cpp/ql/examples>`__.
|
||||
|
||||
.. include:: toc-cpp.rst
|
||||
|
||||
@@ -3,6 +3,8 @@ CodeQL query help for C#
|
||||
|
||||
.. include:: ../reusables/query-help-overview.rst
|
||||
|
||||
For shorter queries that you can use as building blocks when writing your own queries, see the `example queries in the CodeQL repository <https://github.com/github/codeql/tree/main/csharp/ql/examples>`__.
|
||||
These queries are published in the CodeQL query pack ``codeql/csharp-queries`` (`changelog <https://github.com/github/codeql/tree/codeql-cli/latest/csharp/ql/src/CHANGELOG.md>`__, `source <https://github.com/github/codeql/tree/codeql-cli/latest/csharp/ql/src>`__).
|
||||
|
||||
For shorter queries that you can use as building blocks when writing your own queries, see the `example queries in the CodeQL repository <https://github.com/github/codeql/tree/codeql-cli/latest/csharp/ql/examples>`__.
|
||||
|
||||
.. include:: toc-csharp.rst
|
||||
@@ -3,6 +3,8 @@ CodeQL query help for Go
|
||||
|
||||
.. include:: ../reusables/query-help-overview.rst
|
||||
|
||||
For shorter queries that you can use as building blocks when writing your own queries, see the `example queries in the CodeQL repository <https://github.com/github/codeql/tree/main/go/ql/examples>`__.
|
||||
These queries are published in the CodeQL query pack ``codeql/go-queries`` (`changelog <https://github.com/github/codeql/tree/codeql-cli/latest/go/ql/src/CHANGELOG.md>`__, `source <https://github.com/github/codeql/tree/codeql-cli/latest/go/ql/src>`__).
|
||||
|
||||
For shorter queries that you can use as building blocks when writing your own queries, see the `example queries in the CodeQL repository <https://github.com/github/codeql/tree/codeql-cli/latest/go/ql/examples>`__.
|
||||
|
||||
.. include:: toc-go.rst
|
||||
|
||||
@@ -3,6 +3,8 @@ CodeQL query help for Java
|
||||
|
||||
.. include:: ../reusables/query-help-overview.rst
|
||||
|
||||
For shorter queries that you can use as building blocks when writing your own queries, see the `example queries in the CodeQL repository <https://github.com/github/codeql/tree/main/java/ql/examples>`__.
|
||||
These queries are published in the CodeQL query pack ``codeql/java-queries`` (`changelog <https://github.com/github/codeql/tree/codeql-cli/latest/java/ql/src/CHANGELOG.md>`__, `source <https://github.com/github/codeql/tree/codeql-cli/latest/java/ql/src>`__).
|
||||
|
||||
For shorter queries that you can use as building blocks when writing your own queries, see the `example queries in the CodeQL repository <https://github.com/github/codeql/tree/codeql-cli/latest/java/ql/examples>`__.
|
||||
|
||||
.. include:: toc-java.rst
|
||||
|
||||
@@ -3,6 +3,8 @@ CodeQL query help for JavaScript
|
||||
|
||||
.. include:: ../reusables/query-help-overview.rst
|
||||
|
||||
For shorter queries that you can use as building blocks when writing your own queries, see the `example queries in the CodeQL repository <https://github.com/github/codeql/tree/main/javascript/ql/examples>`__.
|
||||
These queries are published in the CodeQL query pack ``codeql/javascript-queries`` (`changelog <https://github.com/github/codeql/tree/codeql-cli/latest/javascript/ql/src/CHANGELOG.md>`__, `source <https://github.com/github/codeql/tree/codeql-cli/latest/javascript/ql/src>`__).
|
||||
|
||||
For shorter queries that you can use as building blocks when writing your own queries, see the `example queries in the CodeQL repository <https://github.com/github/codeql/tree/codeql-cli/latest/javascript/ql/examples>`__.
|
||||
|
||||
.. include:: toc-javascript.rst
|
||||
@@ -3,6 +3,8 @@ CodeQL query help for Python
|
||||
|
||||
.. include:: ../reusables/query-help-overview.rst
|
||||
|
||||
For shorter queries that you can use as building blocks when writing your own queries, see the `example queries in the CodeQL repository <https://github.com/github/codeql/tree/main/python/ql/examples>`__.
|
||||
These queries are published in the CodeQL query pack ``codeql/python-queries`` (`changelog <https://github.com/github/codeql/tree/codeql-cli/latest/python/ql/src/CHANGELOG.md>`__, `source <https://github.com/github/codeql/tree/codeql-cli/latest/python/ql/src>`__).
|
||||
|
||||
For shorter queries that you can use as building blocks when writing your own queries, see the `example queries in the CodeQL repository <https://github.com/github/codeql/tree/codeql-cli/latest/python/ql/examples>`__.
|
||||
|
||||
.. include:: toc-python.rst
|
||||
@@ -3,6 +3,8 @@ CodeQL query help for Ruby
|
||||
|
||||
.. include:: ../reusables/query-help-overview.rst
|
||||
|
||||
For shorter queries that you can use as building blocks when writing your own queries, see the `example queries in the CodeQL repository <https://github.com/github/codeql/tree/main/ruby/ql/examples>`__.
|
||||
These queries are published in the CodeQL query pack ``codeql/ruby-queries`` (`changelog <https://github.com/github/codeql/tree/codeql-cli/latest/ruby/ql/src/CHANGELOG.md>`__, `source <https://github.com/github/codeql/tree/codeql-cli/latest/ruby/ql/src>`__).
|
||||
|
||||
For shorter queries that you can use as building blocks when writing your own queries, see the `example queries in the CodeQL repository <https://github.com/github/codeql/tree/codeql-cli/latest/ruby/ql/examples>`__.
|
||||
|
||||
.. include:: toc-ruby.rst
|
||||
|
||||
@@ -1,6 +1,10 @@
|
||||
C and C++ built-in support
|
||||
================================
|
||||
|
||||
Provided by the current versions of the
|
||||
CodeQL query pack ``codeql/cpp-queries`` (`changelog <https://github.com/github/codeql/tree/codeql-cli/latest/cpp/ql/src/CHANGELOG.md>`__, `source <https://github.com/github/codeql/tree/codeql-cli/latest/cpp/ql/src>`__)
|
||||
and the CodeQL library pack ``codeql/cpp-all`` (`changelog <https://github.com/github/codeql/tree/codeql-cli/latest/cpp/ql/lib/CHANGELOG.md>`__, `source <https://github.com/github/codeql/tree/codeql-cli/latest/cpp/ql/lib>`__).
|
||||
|
||||
.. csv-table::
|
||||
:header-rows: 1
|
||||
:class: fullWidthTable
|
||||
@@ -14,6 +18,10 @@ C and C++ built-in support
|
||||
C# built-in support
|
||||
================================
|
||||
|
||||
Provided by the current versions of the
|
||||
CodeQL query pack ``codeql/csharp-queries`` (`changelog <https://github.com/github/codeql/tree/codeql-cli/latest/csharp/ql/src/CHANGELOG.md>`__, `source <https://github.com/github/codeql/tree/codeql-cli/latest/csharp/ql/src>`__)
|
||||
and the CodeQL library pack ``codeql/csharp-all`` (`changelog <https://github.com/github/codeql/tree/codeql-cli/latest/csharp/ql/lib/CHANGELOG.md>`__, `source <https://github.com/github/codeql/tree/codeql-cli/latest/csharp/ql/lib>`__).
|
||||
|
||||
.. csv-table::
|
||||
:header-rows: 1
|
||||
:class: fullWidthTable
|
||||
@@ -33,6 +41,10 @@ C# built-in support
|
||||
Go built-in support
|
||||
================================
|
||||
|
||||
Provided by the current versions of the
|
||||
CodeQL query pack ``codeql/go-queries`` (`changelog <https://github.com/github/codeql/tree/codeql-cli/latest/go/ql/src/CHANGELOG.md>`__, `source <https://github.com/github/codeql/tree/codeql-cli/latest/go/ql/src>`__)
|
||||
and the CodeQL library pack ``codeql/go-all`` (`changelog <https://github.com/github/codeql/tree/codeql-cli/latest/go/ql/lib/CHANGELOG.md>`__, `source <https://github.com/github/codeql/tree/codeql-cli/latest/go/ql/lib>`__).
|
||||
|
||||
.. csv-table::
|
||||
:header-rows: 1
|
||||
:class: fullWidthTable
|
||||
@@ -84,6 +96,10 @@ Go built-in support
|
||||
Java built-in support
|
||||
==================================
|
||||
|
||||
Provided by the current versions of the
|
||||
CodeQL query pack ``codeql/java-queries`` (`changelog <https://github.com/github/codeql/tree/codeql-cli/latest/java/ql/src/CHANGELOG.md>`__, `source <https://github.com/github/codeql/tree/codeql-cli/latest/java/ql/src>`__)
|
||||
and the CodeQL library pack ``codeql/java-all`` (`changelog <https://github.com/github/codeql/tree/codeql-cli/latest/java/ql/lib/CHANGELOG.md>`__, `source <https://github.com/github/codeql/tree/codeql-cli/latest/java/ql/lib>`__).
|
||||
|
||||
.. csv-table::
|
||||
:header-rows: 1
|
||||
:class: fullWidthTable
|
||||
@@ -113,6 +129,10 @@ Java built-in support
|
||||
JavaScript and TypeScript built-in support
|
||||
=======================================================
|
||||
|
||||
Provided by the current versions of the
|
||||
CodeQL query pack ``codeql/javascript-queries`` (`changelog <https://github.com/github/codeql/tree/codeql-cli/latest/javascript/ql/src/CHANGELOG.md>`__, `source <https://github.com/github/codeql/tree/codeql-cli/latest/javascript/ql/src>`__)
|
||||
and the CodeQL library pack ``codeql/javascript-all`` (`changelog <https://github.com/github/codeql/tree/codeql-cli/latest/javascript/ql/lib/CHANGELOG.md>`__, `source <https://github.com/github/codeql/tree/codeql-cli/latest/javascript/ql/lib>`__).
|
||||
|
||||
.. csv-table::
|
||||
:header-rows: 1
|
||||
:class: fullWidthTable
|
||||
@@ -156,6 +176,10 @@ JavaScript and TypeScript built-in support
|
||||
Python built-in support
|
||||
====================================
|
||||
|
||||
Provided by the current versions of the
|
||||
CodeQL query pack ``codeql/python-queries`` (`changelog <https://github.com/github/codeql/tree/codeql-cli/latest/python/ql/src/CHANGELOG.md>`__, `source <https://github.com/github/codeql/tree/codeql-cli/latest/python/ql/src>`__)
|
||||
and the CodeQL library pack ``codeql/python-all`` (`changelog <https://github.com/github/codeql/tree/codeql-cli/latest/python/ql/lib/CHANGELOG.md>`__, `source <https://github.com/github/codeql/tree/codeql-cli/latest/python/ql/lib>`__).
|
||||
|
||||
.. csv-table::
|
||||
:header-rows: 1
|
||||
:class: fullWidthTable
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
## 0.2.1
|
||||
|
||||
## 0.2.0
|
||||
|
||||
### Deprecated APIs
|
||||
|
||||
1
go/ql/lib/change-notes/released/0.2.1.md
Normal file
1
go/ql/lib/change-notes/released/0.2.1.md
Normal file
@@ -0,0 +1 @@
|
||||
## 0.2.1
|
||||
@@ -1,2 +1,2 @@
|
||||
---
|
||||
lastReleaseVersion: 0.2.0
|
||||
lastReleaseVersion: 0.2.1
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
name: codeql/go-all
|
||||
version: 0.2.1-dev
|
||||
version: 0.2.2-dev
|
||||
groups: go
|
||||
dbscheme: go.dbscheme
|
||||
extractor: go
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
## 0.2.1
|
||||
|
||||
## 0.2.0
|
||||
|
||||
## 0.1.4
|
||||
|
||||
1
go/ql/src/change-notes/released/0.2.1.md
Normal file
1
go/ql/src/change-notes/released/0.2.1.md
Normal file
@@ -0,0 +1 @@
|
||||
## 0.2.1
|
||||
@@ -1,2 +1,2 @@
|
||||
---
|
||||
lastReleaseVersion: 0.2.0
|
||||
lastReleaseVersion: 0.2.1
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
name: codeql/go-queries
|
||||
version: 0.2.1-dev
|
||||
version: 0.2.2-dev
|
||||
groups:
|
||||
- go
|
||||
- queries
|
||||
|
||||
@@ -36,7 +36,7 @@ java.lang,13,,58,,,,,,,,,,,8,,,,,4,,,1,,,,,,,,,,,,,,,46,12
|
||||
java.net,10,3,7,,,,,,,,,,,,,,10,,,,,,,,,,,,,,,,,,,3,7,
|
||||
java.nio,15,,6,,13,,,,,,,,,,,,,,,,,,,,,,,,2,,,,,,,,6,
|
||||
java.sql,11,,,,,,,,,4,,,,,,,,,,,,,,,,7,,,,,,,,,,,,
|
||||
java.util,44,,438,,,,,,,,,,,34,,,,,,5,2,,1,2,,,,,,,,,,,,,24,414
|
||||
java.util,44,,441,,,,,,,,,,,34,,,,,,5,2,,1,2,,,,,,,,,,,,,24,417
|
||||
javax.faces.context,2,7,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,2,,,,7,,
|
||||
javax.jms,,9,57,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,9,57,
|
||||
javax.json,,,123,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,100,23
|
||||
|
||||
|
@@ -15,9 +15,9 @@ Java framework & library support
|
||||
`Apache HttpComponents <https://hc.apache.org/>`_,"``org.apache.hc.core5.*``, ``org.apache.http``",5,136,28,,,3,,,,25
|
||||
`Google Guava <https://guava.dev/>`_,``com.google.common.*``,,728,39,,6,,,,,
|
||||
`JSON-java <https://github.com/stleary/JSON-java>`_,``org.json``,,236,,,,,,,,
|
||||
Java Standard Library,``java.*``,3,549,130,28,,,7,,,10
|
||||
Java Standard Library,``java.*``,3,552,130,28,,,7,,,10
|
||||
Java extensions,"``javax.*``, ``jakarta.*``",63,609,32,,,4,,1,1,2
|
||||
`Spring <https://spring.io/>`_,``org.springframework.*``,29,476,101,,,,19,14,,29
|
||||
Others,"``androidx.slice``, ``cn.hutool.core.codec``, ``com.esotericsoftware.kryo.io``, ``com.esotericsoftware.kryo5.io``, ``com.fasterxml.jackson.core``, ``com.fasterxml.jackson.databind``, ``com.opensymphony.xwork2.ognl``, ``com.rabbitmq.client``, ``com.unboundid.ldap.sdk``, ``com.zaxxer.hikari``, ``flexjson``, ``groovy.lang``, ``groovy.util``, ``jodd.json``, ``kotlin.jvm.internal``, ``net.sf.saxon.s9api``, ``ognl``, ``okhttp3``, ``org.apache.commons.codec``, ``org.apache.commons.jexl2``, ``org.apache.commons.jexl3``, ``org.apache.commons.logging``, ``org.apache.commons.ognl``, ``org.apache.directory.ldap.client.api``, ``org.apache.ibatis.jdbc``, ``org.apache.log4j``, ``org.apache.logging.log4j``, ``org.apache.shiro.codec``, ``org.apache.shiro.jndi``, ``org.codehaus.groovy.control``, ``org.dom4j``, ``org.hibernate``, ``org.jboss.logging``, ``org.jdbi.v3.core``, ``org.jooq``, ``org.mvel2``, ``org.scijava.log``, ``org.slf4j``, ``org.xml.sax``, ``org.xmlpull.v1``, ``play.mvc``, ``ratpack.core.form``, ``ratpack.core.handling``, ``ratpack.core.http``, ``ratpack.exec``, ``ratpack.form``, ``ratpack.func``, ``ratpack.handling``, ``ratpack.http``, ``ratpack.util``, ``retrofit2``",65,395,932,,,,14,18,,3
|
||||
Totals,,217,6410,1474,117,6,10,107,33,1,84
|
||||
Totals,,217,6413,1474,117,6,10,107,33,1,84
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@ import com.github.codeql.utils.versions.functionN
|
||||
import com.github.codeql.utils.versions.getIrStubFromDescriptor
|
||||
import com.semmle.extractor.java.OdasaOutput
|
||||
import org.jetbrains.kotlin.backend.common.extensions.IrPluginContext
|
||||
import org.jetbrains.kotlin.backend.common.lower.parents
|
||||
import org.jetbrains.kotlin.backend.common.pop
|
||||
import org.jetbrains.kotlin.builtins.functions.BuiltInFunctionArity
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
@@ -80,7 +81,7 @@ open class KotlinFileExtractor(
|
||||
}
|
||||
}
|
||||
|
||||
file.declarations.map { extractDeclaration(it, extractPrivateMembers = true, extractFunctionBodies = true) }
|
||||
file.declarations.forEach { extractDeclaration(it, extractPrivateMembers = true, extractFunctionBodies = true) }
|
||||
extractStaticInitializer(file, null)
|
||||
CommentExtractor(this, file, tw.fileId).extract()
|
||||
}
|
||||
@@ -133,7 +134,7 @@ open class KotlinFileExtractor(
|
||||
is IrProperty -> {
|
||||
val parentId = useDeclarationParent(declaration.parent, false)?.cast<DbReftype>()
|
||||
if (parentId != null) {
|
||||
extractProperty(declaration, parentId, extractBackingField = true, extractFunctionBodies = extractFunctionBodies, null, listOf())
|
||||
extractProperty(declaration, parentId, extractBackingField = true, extractFunctionBodies = extractFunctionBodies, extractPrivateMembers = extractPrivateMembers, null, listOf())
|
||||
}
|
||||
Unit
|
||||
}
|
||||
@@ -314,8 +315,21 @@ open class KotlinFileExtractor(
|
||||
val locId = getLocation(c, argsIncludingOuterClasses)
|
||||
tw.writeHasLocation(id, locId)
|
||||
|
||||
// Extract the outer <-> inner class relationship, passing on any type arguments in excess to this class' parameters.
|
||||
extractEnclosingClass(c, id, locId, argsIncludingOuterClasses?.drop(c.typeParameters.size) ?: listOf())
|
||||
// Extract the outer <-> inner class relationship, passing on any type arguments in excess to this class' parameters if this is an inner class.
|
||||
// For example, in `class Outer<T> { inner class Inner<S> { } }`, `Inner<Int, String>` nests within `Outer<Int>` and raw `Inner<>` within `Outer<>`,
|
||||
// but for a similar non-`inner` (in Java terms, static nested) class both `Inner<Int>` and `Inner<>` nest within the unbound type `Outer`.
|
||||
val useBoundOuterType = (c.isInner || c.isLocal) && (c.parents.map { // Would use `firstNotNullOfOrNull`, but this doesn't exist in Kotlin 1.4
|
||||
when(it) {
|
||||
is IrClass -> when {
|
||||
it.typeParameters.isNotEmpty() -> true // Type parameters visible to this class -- extract an enclosing bound or raw type.
|
||||
!(it.isInner || it.isLocal) -> false // No type parameters seen yet, and this is a static class -- extract an enclosing unbound type.
|
||||
else -> null // No type parameters seen here, but may be visible enclosing type parameters; keep searching.
|
||||
}
|
||||
else -> null // Look through enclosing non-class entities (this may need to change)
|
||||
}
|
||||
}.firstOrNull { it != null } ?: false)
|
||||
|
||||
extractEnclosingClass(c, id, locId, if (useBoundOuterType) argsIncludingOuterClasses?.drop(c.typeParameters.size) else listOf())
|
||||
|
||||
return id
|
||||
}
|
||||
@@ -350,7 +364,7 @@ open class KotlinFileExtractor(
|
||||
if (shouldExtractDecl(it, false)) {
|
||||
when(it) {
|
||||
is IrFunction -> extractFunction(it, id, extractBody = false, extractMethodAndParameterTypeAccesses = false, typeParamSubstitution, argsIncludingOuterClasses)
|
||||
is IrProperty -> extractProperty(it, id, extractBackingField = false, extractFunctionBodies = false, typeParamSubstitution, argsIncludingOuterClasses)
|
||||
is IrProperty -> extractProperty(it, id, extractBackingField = false, extractFunctionBodies = false, extractPrivateMembers = false, typeParamSubstitution, argsIncludingOuterClasses)
|
||||
else -> {}
|
||||
}
|
||||
}
|
||||
@@ -392,6 +406,8 @@ open class KotlinFileExtractor(
|
||||
extractDeclInitializers(c.declarations, false) { Pair(blockId, obinitId) }
|
||||
}
|
||||
|
||||
val jvmStaticFqName = FqName("kotlin.jvm.JvmStatic")
|
||||
|
||||
fun extractClassSource(c: IrClass, extractDeclarations: Boolean, extractStaticInitializer: Boolean, extractPrivateMembers: Boolean, extractFunctionBodies: Boolean): Label<out DbClassorinterface> {
|
||||
with("class source", c) {
|
||||
DeclarationStackAdjuster(c).use {
|
||||
@@ -428,9 +444,10 @@ open class KotlinFileExtractor(
|
||||
|
||||
c.typeParameters.mapIndexed { idx, param -> extractTypeParameter(param, idx, javaClass?.typeParameters?.getOrNull(idx)) }
|
||||
if (extractDeclarations) {
|
||||
c.declarations.map { extractDeclaration(it, extractPrivateMembers = extractPrivateMembers, extractFunctionBodies = extractFunctionBodies) }
|
||||
c.declarations.forEach { extractDeclaration(it, extractPrivateMembers = extractPrivateMembers, extractFunctionBodies = extractFunctionBodies) }
|
||||
if (extractStaticInitializer)
|
||||
extractStaticInitializer(c, id)
|
||||
extractJvmStaticProxyMethods(c, id, extractPrivateMembers, extractFunctionBodies)
|
||||
}
|
||||
if (c.isNonCompanionObject) {
|
||||
// For `object MyObject { ... }`, the .class has an
|
||||
@@ -458,7 +475,78 @@ open class KotlinFileExtractor(
|
||||
}
|
||||
}
|
||||
|
||||
private fun extractEnclosingClass(innerDeclaration: IrDeclaration, innerId: Label<out DbClassorinterface>, innerLocId: Label<DbLocation>, parentClassTypeArguments: List<IrTypeArgument>) {
|
||||
private fun extractJvmStaticProxyMethods(c: IrClass, classId: Label<out DbClassorinterface>, extractPrivateMembers: Boolean, extractFunctionBodies: Boolean) {
|
||||
|
||||
// Add synthetic forwarders for any JvmStatic methods or properties:
|
||||
val companionObject = c.companionObject() ?: return
|
||||
|
||||
val cType = c.typeWith()
|
||||
val companionType = companionObject.typeWith()
|
||||
|
||||
fun makeProxyFunction(f: IrFunction) {
|
||||
// Emit a function in class `c` that delegates to the same function defined on `c.CompanionInstance`.
|
||||
val proxyFunctionId = tw.getLabelFor<DbMethod>(getFunctionLabel(f, classId, listOf()))
|
||||
// We extract the function prototype with its ID overridden to belong to `c` not the companion object,
|
||||
// but suppress outputting the body, which we will replace with a delegating call below.
|
||||
forceExtractFunction(f, classId, extractBody = false, extractMethodAndParameterTypeAccesses = extractFunctionBodies, typeSubstitution = null, classTypeArgsIncludingOuterClasses = listOf(), idOverride = proxyFunctionId, locOverride = null, extractOrigin = false)
|
||||
addModifiers(proxyFunctionId, "static")
|
||||
tw.writeCompiler_generated(proxyFunctionId, CompilerGeneratedKinds.JVMSTATIC_PROXY_METHOD.kind)
|
||||
if (extractFunctionBodies) {
|
||||
val realFunctionLocId = tw.getLocation(f)
|
||||
extractExpressionBody(proxyFunctionId, realFunctionLocId).also { returnId ->
|
||||
extractRawMethodAccess(
|
||||
f,
|
||||
realFunctionLocId,
|
||||
f.returnType,
|
||||
proxyFunctionId,
|
||||
returnId,
|
||||
0,
|
||||
returnId,
|
||||
f.valueParameters.size,
|
||||
{ argParent, idxOffset ->
|
||||
f.valueParameters.forEachIndexed { idx, param ->
|
||||
val syntheticParamId = useValueParameter(param, proxyFunctionId)
|
||||
extractVariableAccess(syntheticParamId, param.type, realFunctionLocId, argParent, idxOffset + idx, proxyFunctionId, returnId)
|
||||
}
|
||||
},
|
||||
companionType,
|
||||
{ callId ->
|
||||
val companionField = useCompanionObjectClassInstance(companionObject)?.id
|
||||
extractVariableAccess(companionField, companionType, realFunctionLocId, callId, -1, proxyFunctionId, returnId).also { varAccessId ->
|
||||
extractTypeAccessRecursive(cType, realFunctionLocId, varAccessId, -1, proxyFunctionId, returnId)
|
||||
}
|
||||
},
|
||||
null
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
companionObject.declarations.forEach {
|
||||
if (shouldExtractDecl(it, extractPrivateMembers)) {
|
||||
val wholeDeclAnnotated = it.hasAnnotation(jvmStaticFqName)
|
||||
when(it) {
|
||||
is IrFunction -> {
|
||||
if (wholeDeclAnnotated)
|
||||
makeProxyFunction(it)
|
||||
}
|
||||
is IrProperty -> {
|
||||
it.getter?.let { getter ->
|
||||
if (wholeDeclAnnotated || getter.hasAnnotation(jvmStaticFqName))
|
||||
makeProxyFunction(getter)
|
||||
}
|
||||
it.setter?.let { setter ->
|
||||
if (wholeDeclAnnotated || setter.hasAnnotation(jvmStaticFqName))
|
||||
makeProxyFunction(setter)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If `parentClassTypeArguments` is null, the parent class is a raw type.
|
||||
private fun extractEnclosingClass(innerDeclaration: IrDeclaration, innerId: Label<out DbClassorinterface>, innerLocId: Label<DbLocation>, parentClassTypeArguments: List<IrTypeArgument>?) {
|
||||
with("enclosing class", innerDeclaration) {
|
||||
var parent: IrDeclarationParent? = innerDeclaration.parent
|
||||
while (parent != null) {
|
||||
@@ -725,7 +813,7 @@ open class KotlinFileExtractor(
|
||||
else
|
||||
forceExtractFunction(f, parentId, extractBody, extractMethodAndParameterTypeAccesses, typeSubstitution, classTypeArgsIncludingOuterClasses, null, null)
|
||||
|
||||
private fun forceExtractFunction(f: IrFunction, parentId: Label<out DbReftype>, extractBody: Boolean, extractMethodAndParameterTypeAccesses: Boolean, typeSubstitution: TypeSubstitution?, classTypeArgsIncludingOuterClasses: List<IrTypeArgument>?, idOverride: Label<DbMethod>?, locOverride: Label<DbLocation>?): Label<out DbCallable> {
|
||||
private fun forceExtractFunction(f: IrFunction, parentId: Label<out DbReftype>, extractBody: Boolean, extractMethodAndParameterTypeAccesses: Boolean, typeSubstitution: TypeSubstitution?, classTypeArgsIncludingOuterClasses: List<IrTypeArgument>?, idOverride: Label<DbMethod>?, locOverride: Label<DbLocation>?, extractOrigin: Boolean = true): Label<out DbCallable> {
|
||||
with("function", f) {
|
||||
DeclarationStackAdjuster(f).use {
|
||||
|
||||
@@ -782,13 +870,15 @@ open class KotlinFileExtractor(
|
||||
val methodId = id.cast<DbMethod>()
|
||||
tw.writeMethods(methodId, shortName.nameInDB, "${shortName.nameInDB}$paramsSignature", returnType.javaResult.id, parentId, sourceDeclaration.cast<DbMethod>())
|
||||
tw.writeMethodsKotlinType(methodId, returnType.kotlinResult.id)
|
||||
when (f.origin) {
|
||||
IrDeclarationOrigin.GENERATED_DATA_CLASS_MEMBER ->
|
||||
tw.writeCompiler_generated(methodId, CompilerGeneratedKinds.GENERATED_DATA_CLASS_MEMBER.kind)
|
||||
IrDeclarationOrigin.DEFAULT_PROPERTY_ACCESSOR ->
|
||||
tw.writeCompiler_generated(methodId, CompilerGeneratedKinds.DEFAULT_PROPERTY_ACCESSOR.kind)
|
||||
IrDeclarationOrigin.ENUM_CLASS_SPECIAL_MEMBER ->
|
||||
tw.writeCompiler_generated(methodId, CompilerGeneratedKinds.ENUM_CLASS_SPECIAL_MEMBER.kind)
|
||||
if (extractOrigin) {
|
||||
when (f.origin) {
|
||||
IrDeclarationOrigin.GENERATED_DATA_CLASS_MEMBER ->
|
||||
tw.writeCompiler_generated(methodId, CompilerGeneratedKinds.GENERATED_DATA_CLASS_MEMBER.kind)
|
||||
IrDeclarationOrigin.DEFAULT_PROPERTY_ACCESSOR ->
|
||||
tw.writeCompiler_generated(methodId, CompilerGeneratedKinds.DEFAULT_PROPERTY_ACCESSOR.kind)
|
||||
IrDeclarationOrigin.ENUM_CLASS_SPECIAL_MEMBER ->
|
||||
tw.writeCompiler_generated(methodId, CompilerGeneratedKinds.ENUM_CLASS_SPECIAL_MEMBER.kind)
|
||||
}
|
||||
}
|
||||
|
||||
if (extractMethodAndParameterTypeAccesses) {
|
||||
@@ -809,13 +899,13 @@ open class KotlinFileExtractor(
|
||||
}
|
||||
|
||||
extractVisibility(f, id, f.visibility)
|
||||
|
||||
if (f.isInline) {
|
||||
addModifiers(id, "inline")
|
||||
}
|
||||
if (isStaticFunction(f)) {
|
||||
if (f.shouldExtractAsStatic) {
|
||||
addModifiers(id, "static")
|
||||
}
|
||||
|
||||
if (f is IrSimpleFunction && f.overriddenSymbols.isNotEmpty()) {
|
||||
addModifiers(id, "override")
|
||||
}
|
||||
@@ -865,7 +955,7 @@ open class KotlinFileExtractor(
|
||||
return id
|
||||
}
|
||||
|
||||
private fun extractProperty(p: IrProperty, parentId: Label<out DbReftype>, extractBackingField: Boolean, extractFunctionBodies: Boolean, typeSubstitution: TypeSubstitution?, classTypeArgsIncludingOuterClasses: List<IrTypeArgument>?) {
|
||||
private fun extractProperty(p: IrProperty, parentId: Label<out DbReftype>, extractBackingField: Boolean, extractFunctionBodies: Boolean, extractPrivateMembers: Boolean, typeSubstitution: TypeSubstitution?, classTypeArgsIncludingOuterClasses: List<IrTypeArgument>?) {
|
||||
with("property", p) {
|
||||
if (isFake(p)) return
|
||||
|
||||
@@ -880,7 +970,11 @@ open class KotlinFileExtractor(
|
||||
val getter = p.getter
|
||||
val setter = p.setter
|
||||
|
||||
if (getter != null) {
|
||||
if (getter == null) {
|
||||
if (p.modality != Modality.FINAL || !isExternalDeclaration(p)) {
|
||||
logger.warnElement("IrProperty without a getter", p)
|
||||
}
|
||||
} else if (shouldExtractDecl(getter, extractPrivateMembers)) {
|
||||
val getterId = extractFunction(getter, parentId, extractBody = extractFunctionBodies, extractMethodAndParameterTypeAccesses = extractFunctionBodies, typeSubstitution, classTypeArgsIncludingOuterClasses)?.cast<DbMethod>()
|
||||
if (getterId != null) {
|
||||
tw.writeKtPropertyGetters(id, getterId)
|
||||
@@ -888,13 +982,13 @@ open class KotlinFileExtractor(
|
||||
tw.writeCompiler_generated(getterId, CompilerGeneratedKinds.DELEGATED_PROPERTY_GETTER.kind)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (p.modality != Modality.FINAL || !isExternalDeclaration(p)) {
|
||||
logger.warnElement("IrProperty without a getter", p)
|
||||
}
|
||||
}
|
||||
|
||||
if (setter != null) {
|
||||
if (setter == null) {
|
||||
if (p.isVar && !isExternalDeclaration(p)) {
|
||||
logger.warnElement("isVar property without a setter", p)
|
||||
}
|
||||
} else if (shouldExtractDecl(setter, extractPrivateMembers)) {
|
||||
if (!p.isVar) {
|
||||
logger.warnElement("!isVar property with a setter", p)
|
||||
}
|
||||
@@ -905,10 +999,6 @@ open class KotlinFileExtractor(
|
||||
tw.writeCompiler_generated(setterId, CompilerGeneratedKinds.DELEGATED_PROPERTY_SETTER.kind)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (p.isVar && !isExternalDeclaration(p)) {
|
||||
logger.warnElement("isVar property without a setter", p)
|
||||
}
|
||||
}
|
||||
|
||||
if (bf != null && extractBackingField) {
|
||||
@@ -1013,15 +1103,21 @@ open class KotlinFileExtractor(
|
||||
|
||||
private fun extractExpressionBody(b: IrExpressionBody, callable: Label<out DbCallable>) {
|
||||
with("expression body", b) {
|
||||
val blockId = tw.getFreshIdLabel<DbBlock>()
|
||||
val locId = tw.getLocation(b)
|
||||
tw.writeStmts_block(blockId, callable, 0, callable)
|
||||
tw.writeHasLocation(blockId, locId)
|
||||
extractExpressionBody(callable, locId).also { returnId ->
|
||||
extractExpressionExpr(b.expression, callable, returnId, 0, returnId)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val returnId = tw.getFreshIdLabel<DbReturnstmt>()
|
||||
fun extractExpressionBody(callable: Label<out DbCallable>, locId: Label<out DbLocation>): Label<out DbStmt> {
|
||||
val blockId = tw.getFreshIdLabel<DbBlock>()
|
||||
tw.writeStmts_block(blockId, callable, 0, callable)
|
||||
tw.writeHasLocation(blockId, locId)
|
||||
|
||||
return tw.getFreshIdLabel<DbReturnstmt>().also { returnId ->
|
||||
tw.writeStmts_returnstmt(returnId, blockId, 0, callable)
|
||||
tw.writeHasLocation(returnId, locId)
|
||||
extractExpressionExpr(b.expression, callable, returnId, 0, returnId)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1292,10 +1388,48 @@ open class KotlinFileExtractor(
|
||||
typeArguments: List<IrType> = listOf(),
|
||||
extractClassTypeArguments: Boolean = false) {
|
||||
|
||||
val locId = tw.getLocation(callsite)
|
||||
|
||||
extractRawMethodAccess(
|
||||
syntacticCallTarget,
|
||||
locId,
|
||||
callsite.type,
|
||||
enclosingCallable,
|
||||
callsiteParent,
|
||||
childIdx,
|
||||
enclosingStmt,
|
||||
valueArguments.size,
|
||||
{ argParent, idxOffset -> extractCallValueArguments(argParent, valueArguments, enclosingStmt, enclosingCallable, idxOffset) },
|
||||
dispatchReceiver?.type,
|
||||
dispatchReceiver?.let { { callId -> extractExpressionExpr(dispatchReceiver, enclosingCallable, callId, -1, enclosingStmt) } },
|
||||
extensionReceiver?.let { { argParent -> extractExpressionExpr(extensionReceiver, enclosingCallable, argParent, 0, enclosingStmt) } },
|
||||
typeArguments,
|
||||
extractClassTypeArguments
|
||||
)
|
||||
|
||||
}
|
||||
|
||||
|
||||
fun extractRawMethodAccess(
|
||||
syntacticCallTarget: IrFunction,
|
||||
locId: Label<DbLocation>,
|
||||
returnType: IrType,
|
||||
enclosingCallable: Label<out DbCallable>,
|
||||
callsiteParent: Label<out DbExprparent>,
|
||||
childIdx: Int,
|
||||
enclosingStmt: Label<out DbStmt>,
|
||||
nValueArguments: Int,
|
||||
extractValueArguments: (Label<out DbExpr>, Int) -> Unit,
|
||||
drType: IrType?,
|
||||
extractDispatchReceiver: ((Label<out DbExpr>) -> Unit)?,
|
||||
extractExtensionReceiver: ((Label<out DbExpr>) -> Unit)?,
|
||||
typeArguments: List<IrType> = listOf(),
|
||||
extractClassTypeArguments: Boolean = false) {
|
||||
|
||||
val callTarget = syntacticCallTarget.target.realOverrideTarget
|
||||
val id = tw.getFreshIdLabel<DbMethodaccess>()
|
||||
val type = useType(callsite.type)
|
||||
val locId = tw.getLocation(callsite)
|
||||
val type = useType(returnType)
|
||||
|
||||
tw.writeExprs_methodaccess(id, type.javaResult.id, callsiteParent, childIdx)
|
||||
tw.writeExprsKotlinType(id, type.kotlinResult.id)
|
||||
tw.writeHasLocation(id, locId)
|
||||
@@ -1305,8 +1439,6 @@ open class KotlinFileExtractor(
|
||||
// type arguments at index -2, -3, ...
|
||||
extractTypeArguments(typeArguments, locId, id, enclosingCallable, enclosingStmt, -2, true)
|
||||
|
||||
val drType = dispatchReceiver?.type
|
||||
|
||||
val isFunctionInvoke = drType != null
|
||||
&& drType is IrSimpleType
|
||||
&& drType.isFunctionOrKFunction()
|
||||
@@ -1349,44 +1481,48 @@ open class KotlinFileExtractor(
|
||||
|
||||
tw.writeCallableBinding(id, methodId)
|
||||
|
||||
if (dispatchReceiver != null) {
|
||||
extractExpressionExpr(dispatchReceiver, enclosingCallable, id, -1, enclosingStmt)
|
||||
} else if (isStaticFunction(callTarget)) {
|
||||
if (callTarget.shouldExtractAsStatic) {
|
||||
extractStaticTypeAccessQualifier(callTarget, id, locId, enclosingCallable, enclosingStmt)
|
||||
} else if (extractDispatchReceiver != null) {
|
||||
extractDispatchReceiver(id)
|
||||
}
|
||||
}
|
||||
|
||||
val idxOffset = if (extensionReceiver != null) 1 else 0
|
||||
val idxOffset = if (extractExtensionReceiver != null) 1 else 0
|
||||
|
||||
val argParent = if (isBigArityFunctionInvoke) {
|
||||
extractArrayCreationWithInitializer(id, valueArguments.size + idxOffset, locId, enclosingCallable, enclosingStmt)
|
||||
extractArrayCreationWithInitializer(id, nValueArguments + idxOffset, locId, enclosingCallable, enclosingStmt)
|
||||
} else {
|
||||
id
|
||||
}
|
||||
|
||||
if (extensionReceiver != null) {
|
||||
extractExpressionExpr(extensionReceiver, enclosingCallable, argParent, 0, enclosingStmt)
|
||||
if (extractExtensionReceiver != null) {
|
||||
extractExtensionReceiver(argParent)
|
||||
}
|
||||
|
||||
extractCallValueArguments(argParent, valueArguments, enclosingStmt, enclosingCallable, idxOffset)
|
||||
extractValueArguments(argParent, idxOffset)
|
||||
}
|
||||
|
||||
private fun extractStaticTypeAccessQualifier(target: IrDeclaration, parentExpr: Label<out DbExprparent>, locId: Label<DbLocation>, enclosingCallable: Label<out DbCallable>, enclosingStmt: Label<out DbStmt>) {
|
||||
if (target.isStaticOfClass) {
|
||||
if (target.shouldExtractAsStaticMemberOfClass) {
|
||||
extractTypeAccessRecursive(target.parentAsClass.toRawType(), locId, parentExpr, -1, enclosingCallable, enclosingStmt)
|
||||
} else if (target.isStaticOfFile) {
|
||||
} else if (target.shouldExtractAsStaticMemberOfFile) {
|
||||
extractTypeAccess(useFileClassType(target.parent as IrFile), locId, parentExpr, -1, enclosingCallable, enclosingStmt)
|
||||
}
|
||||
}
|
||||
|
||||
private val IrDeclaration.isStaticOfClass: Boolean
|
||||
get() = this.isStatic && parent is IrClass
|
||||
private val IrDeclaration.shouldExtractAsStaticMemberOfClass: Boolean
|
||||
get() = this.shouldExtractAsStatic && parent is IrClass
|
||||
|
||||
private val IrDeclaration.isStaticOfFile: Boolean
|
||||
get() = this.isStatic && parent is IrFile
|
||||
private val IrDeclaration.shouldExtractAsStaticMemberOfFile: Boolean
|
||||
get() = this.shouldExtractAsStatic && parent is IrFile
|
||||
|
||||
private val IrDeclaration.isStatic: Boolean
|
||||
get() = this is IrSimpleFunction && dispatchReceiverParameter == null ||
|
||||
private fun isStaticAnnotatedNonCompanionMember(f: IrSimpleFunction) =
|
||||
f.parentClassOrNull?.isNonCompanionObject == true &&
|
||||
(f.hasAnnotation(jvmStaticFqName) || f.correspondingPropertySymbol?.owner?.hasAnnotation(jvmStaticFqName) == true)
|
||||
|
||||
private val IrDeclaration.shouldExtractAsStatic: Boolean
|
||||
get() = this is IrSimpleFunction && (isStaticFunction(this) || isStaticAnnotatedNonCompanionMember(this)) ||
|
||||
this is IrField && this.isStatic ||
|
||||
this is IrEnumEntry
|
||||
|
||||
@@ -1988,7 +2124,13 @@ open class KotlinFileExtractor(
|
||||
}
|
||||
isFunction(target, "kotlin", "(some array type)", { isArrayType(it) }, "iterator") && c.origin == IrStatementOrigin.FOR_LOOP_ITERATOR -> {
|
||||
findTopLevelFunctionOrWarn("kotlin.jvm.internal.iterator", "kotlin.jvm.internal.ArrayIteratorKt", c)?.let { iteratorFn ->
|
||||
extractRawMethodAccess(iteratorFn, c, callable, parent, idx, enclosingStmt, listOf(c.dispatchReceiver), null, null, listOf((c.dispatchReceiver!!.type as IrSimpleType).arguments.first().typeOrNull!!))
|
||||
val typeArgs = (c.dispatchReceiver!!.type as IrSimpleType).arguments.map {
|
||||
when(it) {
|
||||
is IrTypeProjection -> it.type
|
||||
else -> pluginContext.irBuiltIns.anyNType
|
||||
}
|
||||
}
|
||||
extractRawMethodAccess(iteratorFn, c, callable, parent, idx, enclosingStmt, listOf(c.dispatchReceiver), null, null, typeArgs)
|
||||
}
|
||||
}
|
||||
isFunction(target, "kotlin", "(some array type)", { isArrayType(it) }, "get") && c.origin == IrStatementOrigin.GET_ARRAY_ELEMENT -> {
|
||||
@@ -2608,78 +2750,22 @@ open class KotlinFileExtractor(
|
||||
val exprParent = parent.expr(e, callable)
|
||||
val owner = e.symbol.owner
|
||||
if (owner is IrValueParameter && owner.index == -1 && !owner.isExtensionReceiver()) {
|
||||
val id = tw.getFreshIdLabel<DbThisaccess>()
|
||||
val type = useType(e.type)
|
||||
val locId = tw.getLocation(e)
|
||||
tw.writeExprs_thisaccess(id, type.javaResult.id, exprParent.parent, exprParent.idx)
|
||||
tw.writeExprsKotlinType(id, type.kotlinResult.id)
|
||||
tw.writeHasLocation(id, locId)
|
||||
tw.writeCallableEnclosingExpr(id, callable)
|
||||
tw.writeStatementEnclosingExpr(id, exprParent.enclosingStmt)
|
||||
|
||||
|
||||
fun extractTypeAccess(parent: IrClass){
|
||||
extractTypeAccessRecursive(parent.typeWith(listOf()), locId, id, 0, callable, exprParent.enclosingStmt)
|
||||
}
|
||||
|
||||
when(val ownerParent = owner.parent) {
|
||||
is IrFunction -> {
|
||||
if (ownerParent.dispatchReceiverParameter == owner &&
|
||||
ownerParent.extensionReceiverParameter != null) {
|
||||
|
||||
val ownerParent2 = ownerParent.parent
|
||||
if (ownerParent2 is IrClass){
|
||||
extractTypeAccess(ownerParent2)
|
||||
} else {
|
||||
logger.errorElement("Unhandled qualifier for this", e)
|
||||
}
|
||||
}
|
||||
}
|
||||
is IrClass -> {
|
||||
if (ownerParent.thisReceiver == owner) {
|
||||
extractTypeAccess(ownerParent)
|
||||
}
|
||||
}
|
||||
else -> {
|
||||
logger.errorElement("Unexpected owner parent for this access: " + ownerParent.javaClass, e)
|
||||
}
|
||||
}
|
||||
extractThisAccess(e, exprParent, callable)
|
||||
} else {
|
||||
val id = tw.getFreshIdLabel<DbVaraccess>()
|
||||
val type = useType(e.type)
|
||||
val locId = tw.getLocation(e)
|
||||
tw.writeExprs_varaccess(id, type.javaResult.id, exprParent.parent, exprParent.idx)
|
||||
tw.writeExprsKotlinType(id, type.kotlinResult.id)
|
||||
tw.writeHasLocation(id, locId)
|
||||
tw.writeCallableEnclosingExpr(id, callable)
|
||||
tw.writeStatementEnclosingExpr(id, exprParent.enclosingStmt)
|
||||
|
||||
val vId = useValueDeclaration(owner)
|
||||
if (vId != null) {
|
||||
tw.writeVariableBinding(id, vId)
|
||||
}
|
||||
extractVariableAccess(useValueDeclaration(owner), e.type, tw.getLocation(e), exprParent.parent, exprParent.idx, callable, exprParent.enclosingStmt)
|
||||
}
|
||||
}
|
||||
is IrGetField -> {
|
||||
val exprParent = parent.expr(e, callable)
|
||||
val id = tw.getFreshIdLabel<DbVaraccess>()
|
||||
val type = useType(e.type)
|
||||
val locId = tw.getLocation(e)
|
||||
tw.writeExprs_varaccess(id, type.javaResult.id, exprParent.parent, exprParent.idx)
|
||||
tw.writeExprsKotlinType(id, type.kotlinResult.id)
|
||||
tw.writeHasLocation(id, locId)
|
||||
tw.writeCallableEnclosingExpr(id, callable)
|
||||
tw.writeStatementEnclosingExpr(id, exprParent.enclosingStmt)
|
||||
val owner = tryReplaceAndroidSyntheticField(e.symbol.owner)
|
||||
val vId = useField(owner)
|
||||
tw.writeVariableBinding(id, vId)
|
||||
tw.writeStatementEnclosingExpr(id, exprParent.enclosingStmt)
|
||||
|
||||
val receiver = e.receiver
|
||||
if (receiver != null) {
|
||||
extractExpressionExpr(receiver, callable, id, -1, exprParent.enclosingStmt)
|
||||
} else if (owner.isStatic) {
|
||||
extractStaticTypeAccessQualifier(owner, id, locId, callable, exprParent.enclosingStmt)
|
||||
val locId = tw.getLocation(e)
|
||||
extractVariableAccess(useField(owner), e.type, locId, exprParent.parent, exprParent.idx, callable, exprParent.enclosingStmt).also { id ->
|
||||
val receiver = e.receiver
|
||||
if (receiver != null) {
|
||||
extractExpressionExpr(receiver, callable, id, -1, exprParent.enclosingStmt)
|
||||
} else if (owner.isStatic) {
|
||||
extractStaticTypeAccessQualifier(owner, id, locId, callable, exprParent.enclosingStmt)
|
||||
}
|
||||
}
|
||||
}
|
||||
is IrGetEnumValue -> {
|
||||
@@ -2980,6 +3066,71 @@ open class KotlinFileExtractor(
|
||||
}
|
||||
}
|
||||
|
||||
private fun extractThisAccess(e: IrGetValue, exprParent: ExprParent, callable: Label<out DbCallable>) {
|
||||
val containingDeclaration = declarationStack.peek()
|
||||
val locId = tw.getLocation(e)
|
||||
val type = useType(e.type)
|
||||
|
||||
if (containingDeclaration.shouldExtractAsStatic && containingDeclaration.parentClassOrNull?.isNonCompanionObject == true) {
|
||||
// Use of `this` in a non-companion object member that will be lowered to a static function -- replace with a reference
|
||||
// to the corresponding static object instance.
|
||||
val instanceField = useObjectClassInstance(containingDeclaration.parentAsClass)
|
||||
extractVariableAccess(instanceField.id, e.type, locId, exprParent.parent, exprParent.idx, callable, exprParent.enclosingStmt).also { varAccessId ->
|
||||
extractStaticTypeAccessQualifier(containingDeclaration, varAccessId, locId, callable, exprParent.enclosingStmt)
|
||||
}
|
||||
} else {
|
||||
val id = tw.getFreshIdLabel<DbThisaccess>()
|
||||
|
||||
tw.writeExprs_thisaccess(id, type.javaResult.id, exprParent.parent, exprParent.idx)
|
||||
tw.writeExprsKotlinType(id, type.kotlinResult.id)
|
||||
tw.writeHasLocation(id, locId)
|
||||
tw.writeCallableEnclosingExpr(id, callable)
|
||||
tw.writeStatementEnclosingExpr(id, exprParent.enclosingStmt)
|
||||
|
||||
fun extractTypeAccess(parent: IrClass) {
|
||||
extractTypeAccessRecursive(parent.typeWith(listOf()), locId, id, 0, callable, exprParent.enclosingStmt)
|
||||
}
|
||||
|
||||
val owner = e.symbol.owner
|
||||
when(val ownerParent = owner.parent) {
|
||||
is IrFunction -> {
|
||||
if (ownerParent.dispatchReceiverParameter == owner &&
|
||||
ownerParent.extensionReceiverParameter != null) {
|
||||
|
||||
val ownerParent2 = ownerParent.parent
|
||||
if (ownerParent2 is IrClass){
|
||||
extractTypeAccess(ownerParent2)
|
||||
} else {
|
||||
logger.errorElement("Unhandled qualifier for this", e)
|
||||
}
|
||||
}
|
||||
}
|
||||
is IrClass -> {
|
||||
if (ownerParent.thisReceiver == owner) {
|
||||
extractTypeAccess(ownerParent)
|
||||
}
|
||||
}
|
||||
else -> {
|
||||
logger.errorElement("Unexpected owner parent for this access: " + ownerParent.javaClass, e)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun extractVariableAccess(variable: Label<out DbVariable>?, irType: IrType, locId: Label<out DbLocation>, parent: Label<out DbExprparent>, idx: Int, callable: Label<out DbCallable>, enclosingStmt: Label<out DbStmt>) =
|
||||
tw.getFreshIdLabel<DbVaraccess>().also {
|
||||
val type = useType(irType)
|
||||
tw.writeExprs_varaccess(it, type.javaResult.id, parent, idx)
|
||||
tw.writeExprsKotlinType(it, type.kotlinResult.id)
|
||||
tw.writeHasLocation(it, locId)
|
||||
tw.writeCallableEnclosingExpr(it, callable)
|
||||
tw.writeStatementEnclosingExpr(it, enclosingStmt)
|
||||
|
||||
if (variable != null) {
|
||||
tw.writeVariableBinding(it, variable)
|
||||
}
|
||||
}
|
||||
|
||||
private fun extractLoop(
|
||||
loop: IrLoop,
|
||||
stmtExprParent: StmtExprParent,
|
||||
@@ -4395,5 +4546,6 @@ open class KotlinFileExtractor(
|
||||
ENUM_CLASS_SPECIAL_MEMBER(5),
|
||||
DELEGATED_PROPERTY_GETTER(6),
|
||||
DELEGATED_PROPERTY_SETTER(7),
|
||||
JVMSTATIC_PROXY_METHOD(8),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,6 +11,7 @@ import org.jetbrains.kotlin.backend.common.lower.parents
|
||||
import org.jetbrains.kotlin.backend.common.lower.parentsWithSelf
|
||||
import org.jetbrains.kotlin.backend.jvm.ir.propertyIfAccessor
|
||||
import org.jetbrains.kotlin.builtins.StandardNames
|
||||
import org.jetbrains.kotlin.codegen.JvmCodegenUtil
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.ir.ObsoleteDescriptorBasedAPI
|
||||
import org.jetbrains.kotlin.ir.declarations.*
|
||||
@@ -23,8 +24,10 @@ import org.jetbrains.kotlin.load.java.BuiltinMethodsWithSpecialGenericSignature
|
||||
import org.jetbrains.kotlin.load.java.JvmAbi
|
||||
import org.jetbrains.kotlin.load.java.sources.JavaSourceElement
|
||||
import org.jetbrains.kotlin.load.java.structure.*
|
||||
import org.jetbrains.kotlin.load.kotlin.getJvmModuleNameForDeserializedDescriptor
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.name.NameUtils
|
||||
import org.jetbrains.kotlin.name.SpecialNames
|
||||
import org.jetbrains.kotlin.types.Variance
|
||||
import org.jetbrains.kotlin.util.OperatorNameConventions
|
||||
@@ -108,14 +111,26 @@ open class KotlinUsesExtractor(
|
||||
}
|
||||
data class TypeResults(val javaResult: TypeResult<DbType>, val kotlinResult: TypeResult<DbKt_type>)
|
||||
|
||||
fun useType(t: IrType, context: TypeContext = TypeContext.OTHER) =
|
||||
fun useType(t: IrType, context: TypeContext = TypeContext.OTHER): TypeResults {
|
||||
when(t) {
|
||||
is IrSimpleType -> useSimpleType(t, context)
|
||||
is IrSimpleType -> return useSimpleType(t, context)
|
||||
else -> {
|
||||
logger.error("Unrecognised IrType: " + t.javaClass)
|
||||
TypeResults(TypeResult(fakeLabel(), "unknown", "unknown"), TypeResult(fakeLabel(), "unknown", "unknown"))
|
||||
return extractErrorType()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun extractErrorType(): TypeResults {
|
||||
val typeId = tw.getLabelFor<DbErrortype>("@\"errorType\"") {
|
||||
tw.writeError_type(it)
|
||||
}
|
||||
val kotlinTypeId = tw.getLabelFor<DbKt_nullable_type>("@\"errorKotlinType\"") {
|
||||
tw.writeKt_nullable_types(it, typeId)
|
||||
}
|
||||
return TypeResults(TypeResult(typeId, null, "<CodeQL error type>"),
|
||||
TypeResult(kotlinTypeId, null, "<CodeQL error type>"))
|
||||
}
|
||||
|
||||
fun getJavaEquivalentClass(c: IrClass) =
|
||||
getJavaEquivalentClassId(c)?.let { pluginContext.referenceClass(it.asSingleFqName()) }?.owner
|
||||
@@ -754,11 +769,25 @@ open class KotlinUsesExtractor(
|
||||
|
||||
data class FunctionNames(val nameInDB: String, val kotlinName: String)
|
||||
|
||||
@OptIn(ObsoleteDescriptorBasedAPI::class)
|
||||
private fun getJvmModuleName(f: IrFunction) =
|
||||
NameUtils.sanitizeAsJavaIdentifier(
|
||||
getJvmModuleNameForDeserializedDescriptor(f.descriptor) ?: JvmCodegenUtil.getModuleName(pluginContext.moduleDescriptor)
|
||||
)
|
||||
|
||||
fun getFunctionShortName(f: IrFunction) : FunctionNames {
|
||||
if (f.origin == IrDeclarationOrigin.LOCAL_FUNCTION_FOR_LAMBDA || f.isAnonymousFunction)
|
||||
return FunctionNames(
|
||||
OperatorNameConventions.INVOKE.asString(),
|
||||
OperatorNameConventions.INVOKE.asString())
|
||||
|
||||
fun getSuffixIfInternal() =
|
||||
if (f.visibility == DescriptorVisibilities.INTERNAL) {
|
||||
"\$" + getJvmModuleName(f)
|
||||
} else {
|
||||
""
|
||||
}
|
||||
|
||||
(f as? IrSimpleFunction)?.correspondingPropertySymbol?.let {
|
||||
val propName = it.owner.name.asString()
|
||||
val getter = it.owner.getter
|
||||
@@ -774,35 +803,26 @@ open class KotlinUsesExtractor(
|
||||
}
|
||||
}
|
||||
|
||||
when (f) {
|
||||
getter -> {
|
||||
val defaultFunctionName = JvmAbi.getterName(propName)
|
||||
val defaultDbName = if (getter.visibility == DescriptorVisibilities.PRIVATE && getter.origin == IrDeclarationOrigin.DEFAULT_PROPERTY_ACCESSOR) {
|
||||
// In JVM these functions don't exist, instead the backing field is accessed directly
|
||||
defaultFunctionName + "\$private"
|
||||
} else {
|
||||
defaultFunctionName
|
||||
}
|
||||
return FunctionNames(getJvmName(getter) ?: defaultDbName, defaultFunctionName)
|
||||
}
|
||||
setter -> {
|
||||
val defaultFunctionName = JvmAbi.setterName(propName)
|
||||
val defaultDbName = if (setter.visibility == DescriptorVisibilities.PRIVATE && setter.origin == IrDeclarationOrigin.DEFAULT_PROPERTY_ACCESSOR) {
|
||||
// In JVM these functions don't exist, instead the backing field is accessed directly
|
||||
defaultFunctionName + "\$private"
|
||||
} else {
|
||||
defaultFunctionName
|
||||
}
|
||||
return FunctionNames(getJvmName(setter) ?: defaultDbName, defaultFunctionName)
|
||||
}
|
||||
val maybeFunctionName = when (f) {
|
||||
getter -> JvmAbi.getterName(propName)
|
||||
setter -> JvmAbi.setterName(propName)
|
||||
else -> {
|
||||
logger.error(
|
||||
"Function has a corresponding property, but is neither the getter nor the setter"
|
||||
)
|
||||
null
|
||||
}
|
||||
}
|
||||
maybeFunctionName?.let { defaultFunctionName ->
|
||||
val suffix = if (f.visibility == DescriptorVisibilities.PRIVATE && f.origin == IrDeclarationOrigin.DEFAULT_PROPERTY_ACCESSOR) {
|
||||
"\$private"
|
||||
} else {
|
||||
getSuffixIfInternal()
|
||||
}
|
||||
return FunctionNames(getJvmName(f) ?: "$defaultFunctionName$suffix", defaultFunctionName)
|
||||
}
|
||||
}
|
||||
return FunctionNames(getJvmName(f) ?: f.name.asString(), f.name.asString())
|
||||
return FunctionNames(getJvmName(f) ?: "${f.name.asString()}${getSuffixIfInternal()}", f.name.asString())
|
||||
}
|
||||
|
||||
// This excludes class type parameters that show up in (at least) constructors' typeParameters list.
|
||||
@@ -970,7 +990,7 @@ open class KotlinUsesExtractor(
|
||||
* allow it to be passed in.
|
||||
*/
|
||||
@OptIn(ObsoleteDescriptorBasedAPI::class)
|
||||
private fun getFunctionLabel(f: IrFunction, maybeParentId: Label<out DbElement>?, classTypeArgsIncludingOuterClasses: List<IrTypeArgument>?) =
|
||||
fun getFunctionLabel(f: IrFunction, maybeParentId: Label<out DbElement>?, classTypeArgsIncludingOuterClasses: List<IrTypeArgument>?) =
|
||||
getFunctionLabel(
|
||||
f.parent,
|
||||
maybeParentId,
|
||||
@@ -1514,7 +1534,7 @@ open class KotlinUsesExtractor(
|
||||
// otherwise two extension properties declared in the same enclosing context will get
|
||||
// clashing trap labels. These are always private, so we can just make up a label without
|
||||
// worrying about their names as seen from Java.
|
||||
val extensionPropertyDiscriminator = getExtensionReceiverType(f)?.let { "extension;${useType(it)}" } ?: ""
|
||||
val extensionPropertyDiscriminator = getExtensionReceiverType(f)?.let { "extension;${useType(it).javaResult.id}" } ?: ""
|
||||
return "@\"field;{$parentId};${extensionPropertyDiscriminator}${f.name.asString()}\""
|
||||
}
|
||||
|
||||
|
||||
@@ -16,7 +16,8 @@ import org.jetbrains.kotlin.psi.psiUtil.startOffset
|
||||
class CommentExtractor(private val fileExtractor: KotlinFileExtractor, private val file: IrFile, private val fileLabel: Label<out DbFile>) {
|
||||
private val tw = fileExtractor.tw
|
||||
private val logger = fileExtractor.logger
|
||||
private val ktFile = Psi2Ir().getKtFile(file)
|
||||
private val psi2Ir = Psi2Ir(logger)
|
||||
private val ktFile = psi2Ir.getKtFile(file)
|
||||
|
||||
fun extract() {
|
||||
if (ktFile == null) {
|
||||
@@ -85,7 +86,7 @@ class CommentExtractor(private val fileExtractor: KotlinFileExtractor, private v
|
||||
val ownerPsi = getKDocOwner(comment) ?: return
|
||||
|
||||
val owners = mutableListOf<IrElement>()
|
||||
file.accept(IrVisitorLookup(ownerPsi, file), owners)
|
||||
file.accept(IrVisitorLookup(psi2Ir, ownerPsi, file), owners)
|
||||
|
||||
for (ownerIr in owners) {
|
||||
val ownerLabel =
|
||||
|
||||
@@ -8,7 +8,7 @@ import org.jetbrains.kotlin.ir.declarations.IrFile
|
||||
import org.jetbrains.kotlin.ir.util.isFakeOverride
|
||||
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
|
||||
|
||||
class IrVisitorLookup(private val psi: PsiElement, private val file: IrFile) :
|
||||
class IrVisitorLookup(private val psi2Ir: Psi2Ir, private val psi: PsiElement, private val file: IrFile) :
|
||||
IrElementVisitor<Unit, MutableCollection<IrElement>> {
|
||||
private val location = psi.getLocation()
|
||||
|
||||
@@ -27,7 +27,7 @@ class IrVisitorLookup(private val psi: PsiElement, private val file: IrFile) :
|
||||
}
|
||||
|
||||
if (location.contains(elementLocation)) {
|
||||
val psiElement = Psi2Ir().findPsiElement(element, file)
|
||||
val psiElement = psi2Ir.findPsiElement(element, file)
|
||||
if (psiElement == psi) {
|
||||
// There can be multiple IrElements that match the same PSI element.
|
||||
data.add(element)
|
||||
@@ -35,4 +35,4 @@ class IrVisitorLookup(private val psi: PsiElement, private val file: IrFile) :
|
||||
}
|
||||
element.acceptChildren(this, data)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -51,6 +51,8 @@ private val specialFunctions = mapOf(
|
||||
makeDescription(FqName("java.lang.Number"), "toFloat") to "floatValue",
|
||||
makeDescription(StandardNames.FqNames.number.toSafe(), "toDouble") to "doubleValue",
|
||||
makeDescription(FqName("java.lang.Number"), "toDouble") to "doubleValue",
|
||||
makeDescription(StandardNames.FqNames.string.toSafe(), "get") to "charAt",
|
||||
makeDescription(FqName("java.lang.String"), "get") to "charAt",
|
||||
)
|
||||
|
||||
private val specialFunctionShortNames = specialFunctions.keys.map { it.functionName }.toSet()
|
||||
|
||||
@@ -1,21 +1,19 @@
|
||||
package com.github.codeql.utils.versions
|
||||
|
||||
import com.github.codeql.FileLogger
|
||||
import com.intellij.psi.PsiElement
|
||||
import org.jetbrains.kotlin.ir.IrElement
|
||||
import org.jetbrains.kotlin.ir.declarations.IrFile
|
||||
import org.jetbrains.kotlin.psi.KtFile
|
||||
import org.jetbrains.kotlin.psi2ir.PsiSourceManager
|
||||
|
||||
class Psi2Ir : Psi2IrFacade {
|
||||
companion object {
|
||||
val psiManager = PsiSourceManager()
|
||||
}
|
||||
|
||||
class Psi2Ir(private val logger: FileLogger) : Psi2IrFacade {
|
||||
override fun getKtFile(irFile: IrFile): KtFile? {
|
||||
return psiManager.getKtFile(irFile)
|
||||
logger.warn("Comment extraction is not supported for Kotlin < 1.5.20")
|
||||
return null
|
||||
}
|
||||
|
||||
override fun findPsiElement(irElement: IrElement, irFile: IrFile): PsiElement? {
|
||||
return psiManager.findPsiElement(irElement, irFile)
|
||||
logger.error("Attempted comment extraction for Kotlin < 1.5.20")
|
||||
return null
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,21 +1,19 @@
|
||||
package com.github.codeql.utils.versions
|
||||
|
||||
import com.github.codeql.FileLogger
|
||||
import com.intellij.psi.PsiElement
|
||||
import org.jetbrains.kotlin.ir.IrElement
|
||||
import org.jetbrains.kotlin.ir.declarations.IrFile
|
||||
import org.jetbrains.kotlin.psi.KtFile
|
||||
import org.jetbrains.kotlin.psi2ir.PsiSourceManager
|
||||
|
||||
class Psi2Ir : Psi2IrFacade {
|
||||
companion object {
|
||||
val psiManager = PsiSourceManager()
|
||||
}
|
||||
|
||||
class Psi2Ir(private val logger: FileLogger) : Psi2IrFacade {
|
||||
override fun getKtFile(irFile: IrFile): KtFile? {
|
||||
return psiManager.getKtFile(irFile)
|
||||
logger.warn("Comment extraction is not supported for Kotlin < 1.5.20")
|
||||
return null
|
||||
}
|
||||
|
||||
override fun findPsiElement(irElement: IrElement, irFile: IrFile): PsiElement? {
|
||||
return psiManager.findPsiElement(irElement, irFile)
|
||||
logger.error("Attempted comment extraction for Kotlin < 1.5.20")
|
||||
return null
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,21 +1,19 @@
|
||||
package com.github.codeql.utils.versions
|
||||
|
||||
import com.github.codeql.FileLogger
|
||||
import com.intellij.psi.PsiElement
|
||||
import org.jetbrains.kotlin.ir.IrElement
|
||||
import org.jetbrains.kotlin.ir.declarations.IrFile
|
||||
import org.jetbrains.kotlin.psi.KtFile
|
||||
import org.jetbrains.kotlin.psi2ir.PsiSourceManager
|
||||
|
||||
class Psi2Ir : Psi2IrFacade {
|
||||
companion object {
|
||||
val psiManager = PsiSourceManager()
|
||||
}
|
||||
|
||||
class Psi2Ir(private val logger: FileLogger) : Psi2IrFacade {
|
||||
override fun getKtFile(irFile: IrFile): KtFile? {
|
||||
return psiManager.getKtFile(irFile)
|
||||
logger.warn("Comment extraction is not supported for Kotlin < 1.5.20")
|
||||
return null
|
||||
}
|
||||
|
||||
override fun findPsiElement(irElement: IrElement, irFile: IrFile): PsiElement? {
|
||||
return psiManager.findPsiElement(irElement, irFile)
|
||||
logger.error("Attempted comment extraction for Kotlin < 1.5.20")
|
||||
return null
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package com.github.codeql.utils.versions
|
||||
|
||||
import com.github.codeql.FileLogger
|
||||
import com.intellij.psi.PsiElement
|
||||
import org.jetbrains.kotlin.backend.common.psi.PsiSourceManager
|
||||
import org.jetbrains.kotlin.backend.jvm.ir.getKtFile
|
||||
@@ -7,7 +8,7 @@ import org.jetbrains.kotlin.ir.IrElement
|
||||
import org.jetbrains.kotlin.ir.declarations.IrFile
|
||||
import org.jetbrains.kotlin.psi.KtFile
|
||||
|
||||
class Psi2Ir: Psi2IrFacade {
|
||||
class Psi2Ir(private val logger: FileLogger): Psi2IrFacade {
|
||||
override fun getKtFile(irFile: IrFile): KtFile? {
|
||||
return irFile.getKtFile()
|
||||
}
|
||||
@@ -15,4 +16,4 @@ class Psi2Ir: Psi2IrFacade {
|
||||
override fun findPsiElement(irElement: IrElement, irFile: IrFile): PsiElement? {
|
||||
return PsiSourceManager.findPsiElement(irElement, irFile)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package com.github.codeql.utils.versions
|
||||
|
||||
import com.github.codeql.FileLogger
|
||||
import com.intellij.psi.PsiElement
|
||||
import org.jetbrains.kotlin.backend.common.psi.PsiSourceManager
|
||||
import org.jetbrains.kotlin.backend.jvm.ir.getKtFile
|
||||
@@ -7,7 +8,7 @@ import org.jetbrains.kotlin.ir.IrElement
|
||||
import org.jetbrains.kotlin.ir.declarations.IrFile
|
||||
import org.jetbrains.kotlin.psi.KtFile
|
||||
|
||||
class Psi2Ir: Psi2IrFacade {
|
||||
class Psi2Ir(private val logger: FileLogger): Psi2IrFacade {
|
||||
override fun getKtFile(irFile: IrFile): KtFile? {
|
||||
return irFile.getKtFile()
|
||||
}
|
||||
@@ -15,4 +16,4 @@ class Psi2Ir: Psi2IrFacade {
|
||||
override fun findPsiElement(irElement: IrElement, irFile: IrFile): PsiElement? {
|
||||
return PsiSourceManager.findPsiElement(irElement, irFile)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package com.github.codeql.utils.versions
|
||||
|
||||
import com.github.codeql.FileLogger
|
||||
import com.intellij.psi.PsiElement
|
||||
import org.jetbrains.kotlin.backend.common.psi.PsiSourceManager
|
||||
import org.jetbrains.kotlin.backend.jvm.ir.getKtFile
|
||||
@@ -7,7 +8,7 @@ import org.jetbrains.kotlin.ir.IrElement
|
||||
import org.jetbrains.kotlin.ir.declarations.IrFile
|
||||
import org.jetbrains.kotlin.psi.KtFile
|
||||
|
||||
class Psi2Ir: Psi2IrFacade {
|
||||
class Psi2Ir(private val logger: FileLogger): Psi2IrFacade {
|
||||
override fun getKtFile(irFile: IrFile): KtFile? {
|
||||
return irFile.getKtFile()
|
||||
}
|
||||
@@ -15,4 +16,4 @@ class Psi2Ir: Psi2IrFacade {
|
||||
override fun findPsiElement(irElement: IrElement, irFile: IrFile): PsiElement? {
|
||||
return PsiSourceManager.findPsiElement(irElement, irFile)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package com.github.codeql.utils.versions
|
||||
|
||||
import com.github.codeql.FileLogger
|
||||
import com.intellij.psi.PsiElement
|
||||
import org.jetbrains.kotlin.backend.common.psi.PsiSourceManager
|
||||
import org.jetbrains.kotlin.backend.jvm.ir.getKtFile
|
||||
@@ -7,7 +8,7 @@ import org.jetbrains.kotlin.ir.IrElement
|
||||
import org.jetbrains.kotlin.ir.declarations.IrFile
|
||||
import org.jetbrains.kotlin.psi.KtFile
|
||||
|
||||
class Psi2Ir: Psi2IrFacade {
|
||||
class Psi2Ir(private val logger: FileLogger): Psi2IrFacade {
|
||||
override fun getKtFile(irFile: IrFile): KtFile? {
|
||||
return irFile.getKtFile()
|
||||
}
|
||||
@@ -15,4 +16,4 @@ class Psi2Ir: Psi2IrFacade {
|
||||
override fun findPsiElement(irElement: IrElement, irFile: IrFile): PsiElement? {
|
||||
return PsiSourceManager.findPsiElement(irElement, irFile)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package com.github.codeql.utils.versions
|
||||
|
||||
import com.github.codeql.FileLogger
|
||||
import com.intellij.psi.PsiElement
|
||||
import org.jetbrains.kotlin.backend.common.psi.PsiSourceManager
|
||||
import org.jetbrains.kotlin.backend.jvm.ir.getKtFile
|
||||
@@ -7,7 +8,7 @@ import org.jetbrains.kotlin.ir.IrElement
|
||||
import org.jetbrains.kotlin.ir.declarations.IrFile
|
||||
import org.jetbrains.kotlin.psi.KtFile
|
||||
|
||||
class Psi2Ir: Psi2IrFacade {
|
||||
class Psi2Ir(private val logger: FileLogger): Psi2IrFacade {
|
||||
override fun getKtFile(irFile: IrFile): KtFile? {
|
||||
return irFile.getKtFile()
|
||||
}
|
||||
@@ -15,4 +16,4 @@ class Psi2Ir: Psi2IrFacade {
|
||||
override fun findPsiElement(irElement: IrElement, irFile: IrFile): PsiElement? {
|
||||
return PsiSourceManager.findPsiElement(irElement, irFile)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,5 +18,6 @@ where
|
||||
m.getFile().isKotlinSourceFile() and
|
||||
// TODO: This ought to have visibility information
|
||||
not m.getName() = "<clinit>" and
|
||||
count(visibility(m)) != 1
|
||||
count(visibility(m)) != 1 and
|
||||
not (count(visibility(m)) = 2 and visibility(m) = "public" and visibility(m) = "internal") // This is a reasonable result, since the JVM symbol is declared public, but Kotlin metadata flags it as internal
|
||||
select m, concat(visibility(m), ", ")
|
||||
|
||||
@@ -48,7 +48,7 @@ c.kt:
|
||||
d.kt:
|
||||
# 0| [CompilationUnit] d
|
||||
# 1| 1: [Class] D
|
||||
# 0| 1: [FieldDeclaration] String bar;
|
||||
# 0| 2: [FieldDeclaration] String bar;
|
||||
# 0| -1: [TypeAccess] String
|
||||
# 0| 0: [StringLiteral] Foobar
|
||||
# 1| 3: [Constructor] D
|
||||
@@ -67,7 +67,7 @@ e.kt:
|
||||
# 0| -3: [TypeAccess] ArrayList<Object>
|
||||
# 0| 0: [IntegerLiteral] 1
|
||||
# 0| 0: [NullLiteral] null
|
||||
# 0| 1: [Method] <fn_LinkedHashMap>
|
||||
# 0| 2: [Method] <fn_LinkedHashMap>
|
||||
# 0| 3: [TypeAccess] Object
|
||||
# 0| 5: [BlockStmt] { ... }
|
||||
# 0| 0: [ReturnStmt] return ...
|
||||
|
||||
@@ -40,43 +40,19 @@ app/src/main/kotlin/testProject/App.kt:
|
||||
# 7| -1: [ThisAccess] Project.this
|
||||
# 7| 0: [TypeAccess] Project
|
||||
# 7| 1: [VarAccess] language
|
||||
# 0| 1: [Method] write$Self
|
||||
# 0| 3: [TypeAccess] Unit
|
||||
#-----| 4: (Parameters)
|
||||
# 0| 0: [Parameter] self
|
||||
# 0| 0: [TypeAccess] Project
|
||||
# 0| 1: [Parameter] output
|
||||
# 0| 0: [TypeAccess] CompositeEncoder
|
||||
# 0| 2: [Parameter] serialDesc
|
||||
# 0| 0: [TypeAccess] SerialDescriptor
|
||||
# 7| 5: [BlockStmt] { ... }
|
||||
# 7| 0: [ExprStmt] <Expr>;
|
||||
# 7| 0: [MethodAccess] encodeStringElement(...)
|
||||
# 7| -1: [VarAccess] output
|
||||
# 7| 0: [VarAccess] serialDesc
|
||||
# 7| 1: [IntegerLiteral] 0
|
||||
# 7| 2: [MethodAccess] getName(...)
|
||||
# 7| -1: [VarAccess] self
|
||||
# 7| 1: [ExprStmt] <Expr>;
|
||||
# 7| 0: [MethodAccess] encodeIntElement(...)
|
||||
# 7| -1: [VarAccess] output
|
||||
# 7| 0: [VarAccess] serialDesc
|
||||
# 7| 1: [IntegerLiteral] 1
|
||||
# 7| 2: [MethodAccess] getLanguage(...)
|
||||
# 7| -1: [VarAccess] self
|
||||
# 0| 1: [Method] component1
|
||||
# 0| 2: [Method] component1
|
||||
# 0| 3: [TypeAccess] String
|
||||
# 0| 5: [BlockStmt] { ... }
|
||||
# 0| 0: [ReturnStmt] return ...
|
||||
# 0| 0: [VarAccess] this.name
|
||||
# 0| -1: [ThisAccess] this
|
||||
# 0| 1: [Method] component2
|
||||
# 0| 3: [Method] component2
|
||||
# 0| 3: [TypeAccess] int
|
||||
# 0| 5: [BlockStmt] { ... }
|
||||
# 0| 0: [ReturnStmt] return ...
|
||||
# 0| 0: [VarAccess] this.language
|
||||
# 0| -1: [ThisAccess] this
|
||||
# 0| 1: [Method] copy
|
||||
# 0| 4: [Method] copy
|
||||
# 0| 3: [TypeAccess] Project
|
||||
#-----| 4: (Parameters)
|
||||
# 8| 0: [Parameter] name
|
||||
@@ -89,41 +65,7 @@ app/src/main/kotlin/testProject/App.kt:
|
||||
# 0| -3: [TypeAccess] Project
|
||||
# 0| 0: [VarAccess] name
|
||||
# 0| 1: [VarAccess] language
|
||||
# 0| 1: [Method] toString
|
||||
# 0| 3: [TypeAccess] String
|
||||
# 0| 5: [BlockStmt] { ... }
|
||||
# 0| 0: [ReturnStmt] return ...
|
||||
# 0| 0: [StringTemplateExpr] "..."
|
||||
# 0| 0: [StringLiteral] Project(
|
||||
# 0| 1: [StringLiteral] name=
|
||||
# 0| 2: [VarAccess] this.name
|
||||
# 0| -1: [ThisAccess] this
|
||||
# 0| 3: [StringLiteral] ,
|
||||
# 0| 4: [StringLiteral] language=
|
||||
# 0| 5: [VarAccess] this.language
|
||||
# 0| -1: [ThisAccess] this
|
||||
# 0| 6: [StringLiteral] )
|
||||
# 0| 1: [Method] hashCode
|
||||
# 0| 3: [TypeAccess] int
|
||||
# 0| 5: [BlockStmt] { ... }
|
||||
# 0| 0: [LocalVariableDeclStmt] var ...;
|
||||
# 0| 1: [LocalVariableDeclExpr] result
|
||||
# 0| 0: [MethodAccess] hashCode(...)
|
||||
# 0| -1: [VarAccess] this.name
|
||||
# 0| -1: [ThisAccess] this
|
||||
# 0| 1: [ExprStmt] <Expr>;
|
||||
# 0| 0: [AssignExpr] ...=...
|
||||
# 0| 0: [VarAccess] result
|
||||
# 0| 1: [MethodAccess] plus(...)
|
||||
# 0| -1: [MethodAccess] times(...)
|
||||
# 0| -1: [VarAccess] result
|
||||
# 0| 0: [IntegerLiteral] 31
|
||||
# 0| 0: [MethodAccess] hashCode(...)
|
||||
# 0| -1: [VarAccess] this.language
|
||||
# 0| -1: [ThisAccess] this
|
||||
# 0| 2: [ReturnStmt] return ...
|
||||
# 0| 0: [VarAccess] result
|
||||
# 0| 1: [Method] equals
|
||||
# 0| 5: [Method] equals
|
||||
# 0| 3: [TypeAccess] boolean
|
||||
#-----| 4: (Parameters)
|
||||
# 0| 0: [Parameter] other
|
||||
@@ -172,27 +114,68 @@ app/src/main/kotlin/testProject/App.kt:
|
||||
# 0| 0: [BooleanLiteral] false
|
||||
# 0| 5: [ReturnStmt] return ...
|
||||
# 0| 0: [BooleanLiteral] true
|
||||
# 7| 9: [Class] Companion
|
||||
# 0| 1: [Method] serializer
|
||||
# 0| 3: [TypeAccess] KSerializer<Project>
|
||||
# 0| 0: [TypeAccess] Project
|
||||
# 7| 5: [BlockStmt] { ... }
|
||||
# 7| 0: [ReturnStmt] return ...
|
||||
# 7| 0: [VarAccess] INSTANCE
|
||||
# 7| 2: [Constructor] Companion
|
||||
# 7| 5: [BlockStmt] { ... }
|
||||
# 7| 0: [SuperConstructorInvocationStmt] super(...)
|
||||
# 7| 1: [BlockStmt] { ... }
|
||||
# 7| 9: [Class] $serializer
|
||||
# 0| 1: [Method] getDescriptor
|
||||
# 0| 3: [TypeAccess] SerialDescriptor
|
||||
# 0| 5: [BlockStmt] { ... }
|
||||
# 0| 0: [ReturnStmt] return ...
|
||||
# 0| 0: [VarAccess] this.descriptor
|
||||
# 0| 6: [Method] hashCode
|
||||
# 0| 3: [TypeAccess] int
|
||||
# 0| 5: [BlockStmt] { ... }
|
||||
# 0| 0: [LocalVariableDeclStmt] var ...;
|
||||
# 0| 1: [LocalVariableDeclExpr] result
|
||||
# 0| 0: [MethodAccess] hashCode(...)
|
||||
# 0| -1: [VarAccess] this.name
|
||||
# 0| -1: [ThisAccess] this
|
||||
# 0| 1: [ExprStmt] <Expr>;
|
||||
# 0| 0: [AssignExpr] ...=...
|
||||
# 0| 0: [VarAccess] result
|
||||
# 0| 1: [MethodAccess] plus(...)
|
||||
# 0| -1: [MethodAccess] times(...)
|
||||
# 0| -1: [VarAccess] result
|
||||
# 0| 0: [IntegerLiteral] 31
|
||||
# 0| 0: [MethodAccess] hashCode(...)
|
||||
# 0| -1: [VarAccess] this.language
|
||||
# 0| -1: [ThisAccess] this
|
||||
# 0| 2: [ReturnStmt] return ...
|
||||
# 0| 0: [VarAccess] result
|
||||
# 0| 7: [Method] toString
|
||||
# 0| 3: [TypeAccess] String
|
||||
# 0| 5: [BlockStmt] { ... }
|
||||
# 0| 0: [ReturnStmt] return ...
|
||||
# 0| 0: [StringTemplateExpr] "..."
|
||||
# 0| 0: [StringLiteral] Project(
|
||||
# 0| 1: [StringLiteral] name=
|
||||
# 0| 2: [VarAccess] this.name
|
||||
# 0| -1: [ThisAccess] this
|
||||
# 0| 3: [StringLiteral] ,
|
||||
# 0| 4: [StringLiteral] language=
|
||||
# 0| 5: [VarAccess] this.language
|
||||
# 0| -1: [ThisAccess] this
|
||||
# 0| 6: [StringLiteral] )
|
||||
# 0| 8: [Method] write$Self
|
||||
# 0| 3: [TypeAccess] Unit
|
||||
#-----| 4: (Parameters)
|
||||
# 0| 0: [Parameter] self
|
||||
# 0| 0: [TypeAccess] Project
|
||||
# 0| 1: [Parameter] output
|
||||
# 0| 0: [TypeAccess] CompositeEncoder
|
||||
# 0| 2: [Parameter] serialDesc
|
||||
# 0| 0: [TypeAccess] SerialDescriptor
|
||||
# 7| 5: [BlockStmt] { ... }
|
||||
# 7| 0: [ExprStmt] <Expr>;
|
||||
# 7| 0: [MethodAccess] encodeStringElement(...)
|
||||
# 7| -1: [VarAccess] output
|
||||
# 7| 0: [VarAccess] serialDesc
|
||||
# 7| 1: [IntegerLiteral] 0
|
||||
# 7| 2: [MethodAccess] getName(...)
|
||||
# 7| -1: [VarAccess] self
|
||||
# 7| 1: [ExprStmt] <Expr>;
|
||||
# 7| 0: [MethodAccess] encodeIntElement(...)
|
||||
# 7| -1: [VarAccess] output
|
||||
# 7| 0: [VarAccess] serialDesc
|
||||
# 7| 1: [IntegerLiteral] 1
|
||||
# 7| 2: [MethodAccess] getLanguage(...)
|
||||
# 7| -1: [VarAccess] self
|
||||
# 7| 9: [Class] $serializer
|
||||
# 0| 1: [FieldDeclaration] SerialDescriptor descriptor;
|
||||
# 0| -1: [TypeAccess] SerialDescriptor
|
||||
# 0| 1: [Method] childSerializers
|
||||
# 0| 2: [Method] childSerializers
|
||||
# 0| 3: [TypeAccess] KSerializer<?>[]
|
||||
# 0| 0: [TypeAccess] KSerializer<?>
|
||||
# 0| 0: [WildcardTypeAccess] ? ...
|
||||
@@ -204,7 +187,7 @@ app/src/main/kotlin/testProject/App.kt:
|
||||
# 7| 1: [VarAccess] INSTANCE
|
||||
# 7| -1: [TypeAccess] KSerializer<?>
|
||||
# 7| 0: [IntegerLiteral] 2
|
||||
# 0| 1: [Method] deserialize
|
||||
# 0| 3: [Method] deserialize
|
||||
# 0| 3: [TypeAccess] Project
|
||||
#-----| 4: (Parameters)
|
||||
# 0| 0: [Parameter] decoder
|
||||
@@ -342,7 +325,13 @@ app/src/main/kotlin/testProject/App.kt:
|
||||
# 7| 1: [VarAccess] tmp4_local0
|
||||
# 7| 2: [VarAccess] tmp5_local1
|
||||
# 7| 3: [NullLiteral] null
|
||||
# 0| 1: [Method] serialize
|
||||
# 0| 4: [Method] getDescriptor
|
||||
# 0| 3: [TypeAccess] SerialDescriptor
|
||||
# 0| 5: [BlockStmt] { ... }
|
||||
# 0| 0: [ReturnStmt] return ...
|
||||
# 0| 0: [VarAccess] this.descriptor
|
||||
# 0| -1: [ThisAccess] this
|
||||
# 0| 5: [Method] serialize
|
||||
# 0| 3: [TypeAccess] Unit
|
||||
#-----| 4: (Parameters)
|
||||
# 0| 0: [Parameter] encoder
|
||||
@@ -397,6 +386,17 @@ app/src/main/kotlin/testProject/App.kt:
|
||||
# 7| -1: [ThisAccess] $serializer.this
|
||||
# 7| 0: [TypeAccess] $serializer
|
||||
# 7| 1: [VarAccess] tmp0_serialDesc
|
||||
# 7| 10: [Class] Companion
|
||||
# 0| 1: [Method] serializer
|
||||
# 0| 3: [TypeAccess] KSerializer<Project>
|
||||
# 0| 0: [TypeAccess] Project
|
||||
# 7| 5: [BlockStmt] { ... }
|
||||
# 7| 0: [ReturnStmt] return ...
|
||||
# 7| 0: [VarAccess] INSTANCE
|
||||
# 7| 2: [Constructor] Companion
|
||||
# 7| 5: [BlockStmt] { ... }
|
||||
# 7| 0: [SuperConstructorInvocationStmt] super(...)
|
||||
# 7| 1: [BlockStmt] { ... }
|
||||
# 8| 11: [Constructor] Project
|
||||
#-----| 4: (Parameters)
|
||||
# 8| 0: [Parameter] name
|
||||
@@ -412,21 +412,21 @@ app/src/main/kotlin/testProject/App.kt:
|
||||
# 8| 1: [ExprStmt] <Expr>;
|
||||
# 8| 0: [KtInitializerAssignExpr] ...=...
|
||||
# 8| 0: [VarAccess] language
|
||||
# 8| 12: [Method] getName
|
||||
# 8| 12: [FieldDeclaration] String name;
|
||||
# 8| -1: [TypeAccess] String
|
||||
# 8| 0: [VarAccess] name
|
||||
# 8| 13: [Method] getName
|
||||
# 8| 3: [TypeAccess] String
|
||||
# 8| 5: [BlockStmt] { ... }
|
||||
# 8| 0: [ReturnStmt] return ...
|
||||
# 8| 0: [VarAccess] this.name
|
||||
# 8| -1: [ThisAccess] this
|
||||
# 8| 12: [FieldDeclaration] String name;
|
||||
# 8| -1: [TypeAccess] String
|
||||
# 8| 0: [VarAccess] name
|
||||
# 8| 14: [Method] getLanguage
|
||||
# 8| 3: [TypeAccess] int
|
||||
# 8| 5: [BlockStmt] { ... }
|
||||
# 8| 0: [ReturnStmt] return ...
|
||||
# 8| 0: [VarAccess] this.language
|
||||
# 8| -1: [ThisAccess] this
|
||||
# 8| 14: [FieldDeclaration] int language;
|
||||
# 8| 15: [FieldDeclaration] int language;
|
||||
# 8| -1: [TypeAccess] int
|
||||
# 8| 0: [VarAccess] language
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
public class User {
|
||||
|
||||
public static int test(Test1 test1, Test2 test2, Test3 test3) {
|
||||
|
||||
return test1.f$main() + test2.f$mymodule() + test3.f$reservedchars___();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
| User.java:3:21:3:24 | test |
|
||||
| test1.kt:3:12:3:22 | f$main |
|
||||
| test2.kt:3:12:3:22 | f$mymodule |
|
||||
| test3.kt:3:12:3:22 | f$reservedchars___ |
|
||||
@@ -0,0 +1,3 @@
|
||||
from create_database_utils import *
|
||||
|
||||
run_codeql_database_create(["kotlinc test1.kt", "kotlinc test2.kt -module-name mymodule", "kotlinc test3.kt -module-name reservedchars\\\"${}/", "javac User.java -cp ." ], lang="java")
|
||||
@@ -0,0 +1,5 @@
|
||||
import java
|
||||
|
||||
from Method m
|
||||
where m.fromSource()
|
||||
select m
|
||||
@@ -0,0 +1,5 @@
|
||||
public class Test1 {
|
||||
|
||||
internal fun f() = 1
|
||||
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
public class Test2 {
|
||||
|
||||
internal fun f() = 2
|
||||
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
public class Test3 {
|
||||
|
||||
internal fun f() = 3
|
||||
|
||||
}
|
||||
@@ -21,6 +21,15 @@ public class JavaUser {
|
||||
String result4 = d.identity("goodbye");
|
||||
Short result5 = e.returnSixth(1, "hello", 1.0f, 1.0, 1L, (short)1);
|
||||
|
||||
OuterGeneric<String>.InnerNotGeneric innerGetterTest = (new OuterGeneric<String>()).getInnerNotGeneric();
|
||||
OuterNotGeneric.InnerGeneric<String> innerGetterTest2 = (new OuterNotGeneric()).getInnerGeneric();
|
||||
|
||||
TypeParamVisibility<String> tpv = new TypeParamVisibility<String>();
|
||||
TypeParamVisibility<String>.VisibleBecauseInner<String> visibleBecauseInner = tpv.getVisibleBecauseInner();
|
||||
TypeParamVisibility<String>.VisibleBecauseInnerIndirectContainer.VisibleBecauseInnerIndirect<String> visibleBecauseInnerIndirect = tpv.getVisibleBecauseInnerIndirect();
|
||||
TypeParamVisibility.NotVisibleBecauseStatic<String> notVisibleBecauseStatic = tpv.getNotVisibleBecauseStatic();
|
||||
TypeParamVisibility.NotVisibleBecauseStaticIndirectContainer.NotVisibleBecauseStaticIndirect<String> notVisibleBecauseStaticIndirect = tpv.getNotVisibleBecauseStaticIndirect();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -22,6 +22,15 @@ class User {
|
||||
val result4 = d.identity("goodbye")
|
||||
val result5 = e.returnSixth(1, "hello", 1.0f, 1.0, 1L, 1.toShort())
|
||||
|
||||
val innerGetterTest = OuterGeneric<String>().getInnerNotGeneric()
|
||||
val innerGetterTest2 = OuterNotGeneric().getInnerGeneric()
|
||||
|
||||
val tpv = TypeParamVisibility<String>()
|
||||
val visibleBecauseInner = tpv.getVisibleBecauseInner();
|
||||
val visibleBecauseInnerIndirect = tpv.getVisibleBecauseInnerIndirect()
|
||||
val notVisibleBecauseStatic = tpv.getNotVisibleBecauseStatic()
|
||||
val notVisibleBecauseStaticIndirect = tpv.getNotVisibleBecauseStaticIndirect()
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -8,6 +8,8 @@ public class OuterGeneric<T> {
|
||||
|
||||
}
|
||||
|
||||
public InnerNotGeneric getInnerNotGeneric() { return null; }
|
||||
|
||||
public class InnerGeneric<S> {
|
||||
|
||||
public <R> InnerGeneric(R r) { }
|
||||
|
||||
@@ -8,4 +8,10 @@ public class OuterNotGeneric {
|
||||
|
||||
}
|
||||
|
||||
public InnerGeneric<String> getInnerGeneric() {
|
||||
|
||||
return new InnerGeneric<String>();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user