mirror of
https://github.com/github/codeql.git
synced 2026-06-19 20:01:09 +02:00
Compare commits
411 Commits
yoff/pytho
...
bazookamus
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
93a26cb6c0 | ||
|
|
554576c031 | ||
|
|
2686026608 | ||
|
|
1d69c30ec1 | ||
|
|
65a3153066 | ||
|
|
779309edb1 | ||
|
|
5016fcb396 | ||
|
|
142a72c77b | ||
|
|
330e904449 | ||
|
|
f844cd3754 | ||
|
|
3a3ec1be90 | ||
|
|
c747352f41 | ||
|
|
dfdd12190e | ||
|
|
63057db753 | ||
|
|
21f8caf153 | ||
|
|
9b34cfa362 | ||
|
|
944d76de44 | ||
|
|
b7ef551b52 | ||
|
|
00427d204c | ||
|
|
e618883866 | ||
|
|
c7c1eca415 | ||
|
|
3dd3e2c643 | ||
|
|
55f2f041ee | ||
|
|
004a5b4645 | ||
|
|
fefe01ecbf | ||
|
|
7960c5c291 | ||
|
|
57f20064ba | ||
|
|
1f9899d7db | ||
|
|
dd61dd2d74 | ||
|
|
47c2c9e763 | ||
|
|
1cb5be52d0 | ||
|
|
ea7510bf72 | ||
|
|
415857cacb | ||
|
|
ac3e38e7ad | ||
|
|
d72144646a | ||
|
|
b15a1afa24 | ||
|
|
c444f41a3f | ||
|
|
199fd864ad | ||
|
|
929870d828 | ||
|
|
1154db4f86 | ||
|
|
890969433f | ||
|
|
71daa20313 | ||
|
|
0a065c93de | ||
|
|
6161922ba4 | ||
|
|
df416fa542 | ||
|
|
274f014d31 | ||
|
|
b9025a54af | ||
|
|
1d11151135 | ||
|
|
e6e5f0dffd | ||
|
|
c12cf88c52 | ||
|
|
3654205ae2 | ||
|
|
027f302932 | ||
|
|
72f34c2b3b | ||
|
|
2eb9c54456 | ||
|
|
4d70c5f87e | ||
|
|
4bfc2fd791 | ||
|
|
7ef19112e4 | ||
|
|
c5dc05483b | ||
|
|
7f3181b145 | ||
|
|
e94d279234 | ||
|
|
48aefff964 | ||
|
|
c5e020c68c | ||
|
|
8778e881cb | ||
|
|
36c1796ef7 | ||
|
|
8f965a9614 | ||
|
|
d72372c246 | ||
|
|
ef67311af2 | ||
|
|
ae57ca7e65 | ||
|
|
d287f0cf0b | ||
|
|
f143dad1b2 | ||
|
|
01454d76c2 | ||
|
|
859ad1d8d0 | ||
|
|
b10abb63d9 | ||
|
|
44e23638a4 | ||
|
|
5e606b7bef | ||
|
|
84e7c2de6c | ||
|
|
0df9aac69c | ||
|
|
bc9fa6ba13 | ||
|
|
c08c0e9ae5 | ||
|
|
4f1d6f472d | ||
|
|
78d95719a5 | ||
|
|
c31b594bbc | ||
|
|
66db0d42a9 | ||
|
|
7039c4a2be | ||
|
|
746631d3dc | ||
|
|
b9b15af308 | ||
|
|
f658bc9b39 | ||
|
|
8cb4b9b118 | ||
|
|
175c4f1b0d | ||
|
|
ab4f170780 | ||
|
|
4ad3a44aab | ||
|
|
686e98c6ff | ||
|
|
14c72def96 | ||
|
|
d0841d2283 | ||
|
|
568de02e98 | ||
|
|
651770b412 | ||
|
|
7c11f19445 | ||
|
|
7ae03377cd | ||
|
|
6934aa0e39 | ||
|
|
9c65082189 | ||
|
|
359e272577 | ||
|
|
23567eba3d | ||
|
|
ce9e61dbfd | ||
|
|
daefaff969 | ||
|
|
4bc083fd7f | ||
|
|
89c1d66f90 | ||
|
|
b9670ef831 | ||
|
|
6000c18c24 | ||
|
|
e81a3bcbc3 | ||
|
|
7d6d5bfb4a | ||
|
|
f83adb55ce | ||
|
|
5608369abe | ||
|
|
346d140c87 | ||
|
|
9f0feb467a | ||
|
|
434a99447e | ||
|
|
d389ea4039 | ||
|
|
ff61344afa | ||
|
|
fe8c029ac7 | ||
|
|
8d46bfcbd4 | ||
|
|
f0640d78d2 | ||
|
|
fb9e4a8c40 | ||
|
|
3c407f77a9 | ||
|
|
9465a1d063 | ||
|
|
072c4837d2 | ||
|
|
ee040da575 | ||
|
|
524330c188 | ||
|
|
7d54669696 | ||
|
|
951a26a01a | ||
|
|
2bbcc1e88c | ||
|
|
d101e45efc | ||
|
|
912dc9c0bd | ||
|
|
eea406f622 | ||
|
|
17b9a66895 | ||
|
|
de7afcaec3 | ||
|
|
f3ec7087e3 | ||
|
|
0a0867a34f | ||
|
|
4f93dfbd6a | ||
|
|
b280dd51f2 | ||
|
|
d8e10b8c21 | ||
|
|
01b463f442 | ||
|
|
bea5522473 | ||
|
|
eedef515f7 | ||
|
|
90d888de7f | ||
|
|
3f0af57c89 | ||
|
|
a646dfc4b9 | ||
|
|
5633004757 | ||
|
|
6d13ff7952 | ||
|
|
05d41c7f8d | ||
|
|
d9be99c73d | ||
|
|
330b4e7ebc | ||
|
|
0f7e36958d | ||
|
|
02c37321d0 | ||
|
|
2f473572fa | ||
|
|
edc1c150a0 | ||
|
|
d9152392ce | ||
|
|
9c9c89615e | ||
|
|
b8edde6d44 | ||
|
|
5c8857ada2 | ||
|
|
01fe081f36 | ||
|
|
9078b511c6 | ||
|
|
1ac079d066 | ||
|
|
de281fc00c | ||
|
|
29b0c286a7 | ||
|
|
ad18659373 | ||
|
|
a4bf2b8f58 | ||
|
|
838d06c53f | ||
|
|
913dcb1190 | ||
|
|
a375e186ed | ||
|
|
923fe2dcb9 | ||
|
|
befb557bfd | ||
|
|
642259cd51 | ||
|
|
73bc2d70ae | ||
|
|
0d984588f9 | ||
|
|
17dbf03c6d | ||
|
|
ef5678708c | ||
|
|
7bd5abf809 | ||
|
|
e612db2ec9 | ||
|
|
a4585d8d94 | ||
|
|
7795884946 | ||
|
|
b4a9689341 | ||
|
|
6a8e20a0c8 | ||
|
|
4c411bbcb5 | ||
|
|
b60bf8c79f | ||
|
|
ef00aa2567 | ||
|
|
6d0968744b | ||
|
|
98f147556a | ||
|
|
3693185b6b | ||
|
|
1c1d26453d | ||
|
|
4c1a0058bf | ||
|
|
f5919875b7 | ||
|
|
990913519d | ||
|
|
e22f9fadd7 | ||
|
|
071a0e3d7d | ||
|
|
a92349683e | ||
|
|
8ce543bf4d | ||
|
|
da777a455d | ||
|
|
f4f17b01c1 | ||
|
|
1c47084479 | ||
|
|
c241049384 | ||
|
|
8d456df26f | ||
|
|
72fcf27d1a | ||
|
|
0cea01c22f | ||
|
|
a473565256 | ||
|
|
01173bf383 | ||
|
|
d0ffde8c45 | ||
|
|
b6c951e90c | ||
|
|
c47135a40b | ||
|
|
2cb0851900 | ||
|
|
3cbc8f0262 | ||
|
|
e370af6444 | ||
|
|
61be37d718 | ||
|
|
da05992a09 | ||
|
|
cc1ea25856 | ||
|
|
5a38cbd5d5 | ||
|
|
e93bc11f6f | ||
|
|
cf6d94cf8a | ||
|
|
292fc8b777 | ||
|
|
a1759d9834 | ||
|
|
6b74874372 | ||
|
|
ef29d22c75 | ||
|
|
9acf0d6dff | ||
|
|
1f91f915c7 | ||
|
|
ba8eebe2b5 | ||
|
|
dc1409e5f4 | ||
|
|
f4dc86e645 | ||
|
|
284f42bb9e | ||
|
|
44c8a97e2f | ||
|
|
1d884a3979 | ||
|
|
8c35e089d8 | ||
|
|
e1fde60988 | ||
|
|
1b29c12049 | ||
|
|
d38091fe28 | ||
|
|
303cb11609 | ||
|
|
b877943b42 | ||
|
|
0aa1abe432 | ||
|
|
b6521e7c0e | ||
|
|
e8f7454ea1 | ||
|
|
3a90e8c77e | ||
|
|
58b1a05985 | ||
|
|
2f3524de74 | ||
|
|
b32573b060 | ||
|
|
078d15e165 | ||
|
|
e87f7fb3f7 | ||
|
|
c170002fb1 | ||
|
|
14e3ee2fb0 | ||
|
|
50e0354911 | ||
|
|
101812310c | ||
|
|
c87bfd5f28 | ||
|
|
05e21adc53 | ||
|
|
f67d0ea961 | ||
|
|
5217ede621 | ||
|
|
cd2398aeea | ||
|
|
59908124c1 | ||
|
|
d6892eaf0d | ||
|
|
d2972cb53f | ||
|
|
5576d30780 | ||
|
|
da999ee440 | ||
|
|
3da195f50f | ||
|
|
93a4b427e3 | ||
|
|
0430c71318 | ||
|
|
52f2a5825a | ||
|
|
d55ff83568 | ||
|
|
f34275636c | ||
|
|
0a801440b9 | ||
|
|
7edf0100cc | ||
|
|
167c837088 | ||
|
|
6f2cc43f32 | ||
|
|
5042fdee84 | ||
|
|
04341c47bd | ||
|
|
af45e53e77 | ||
|
|
b27d08ee32 | ||
|
|
d11fc3a00e | ||
|
|
20ce679d61 | ||
|
|
f62ebef9e0 | ||
|
|
c3ef1ddd64 | ||
|
|
dede5bc49b | ||
|
|
ad97b6dd64 | ||
|
|
9d5dfea5c5 | ||
|
|
dc0c7d7ec2 | ||
|
|
aaa3b363e1 | ||
|
|
61a5cece56 | ||
|
|
566a92e555 | ||
|
|
9dbe9adb00 | ||
|
|
be9c785cb2 | ||
|
|
1fd31d0ddd | ||
|
|
c319680589 | ||
|
|
434850edd3 | ||
|
|
c4e3720d8a | ||
|
|
0547e9c98d | ||
|
|
703cea2b65 | ||
|
|
e6e8e3d005 | ||
|
|
adc9b7714b | ||
|
|
e706c5f444 | ||
|
|
8a1e6d4f64 | ||
|
|
1a747dd8be | ||
|
|
28bb1a6870 | ||
|
|
45b1253b23 | ||
|
|
c99dab1d71 | ||
|
|
f3e3647209 | ||
|
|
8d099cbe38 | ||
|
|
9618e9b35c | ||
|
|
2a3cff382c | ||
|
|
c610af88d3 | ||
|
|
fa63dad1d1 | ||
|
|
019a5c01ad | ||
|
|
5fb75ac987 | ||
|
|
c1c9287535 | ||
|
|
d1226b71de | ||
|
|
71a363545a | ||
|
|
3f3bed62d3 | ||
|
|
21f216af8c | ||
|
|
1751d70c62 | ||
|
|
ac8eb50c26 | ||
|
|
1ecdc3614f | ||
|
|
e3b3888bee | ||
|
|
ef9306d82c | ||
|
|
56822f8ee1 | ||
|
|
62207f152c | ||
|
|
d5f94475b5 | ||
|
|
00e95a0757 | ||
|
|
c695c151ea | ||
|
|
ab4a575243 | ||
|
|
d2f474d998 | ||
|
|
b38440490a | ||
|
|
22b08f1ea4 | ||
|
|
5e5a0437e1 | ||
|
|
e18448dd59 | ||
|
|
a16f1c555c | ||
|
|
43c1152634 | ||
|
|
caae5a8bf1 | ||
|
|
cfb18c2477 | ||
|
|
1a82a682e9 | ||
|
|
8b6f969cdb | ||
|
|
f4da0df3c7 | ||
|
|
9bc0c1b1ab | ||
|
|
aee33a0cc9 | ||
|
|
4c31866910 | ||
|
|
09371339d7 | ||
|
|
df15a719cb | ||
|
|
2d581504f7 | ||
|
|
9f211cebd5 | ||
|
|
8393b40b59 | ||
|
|
f8ab76e1ba | ||
|
|
812e8e6b34 | ||
|
|
80c6f082d1 | ||
|
|
d95d99848c | ||
|
|
8937e22735 | ||
|
|
37589dd8a0 | ||
|
|
a159dc1c66 | ||
|
|
7718fe40a0 | ||
|
|
aeb82858d7 | ||
|
|
c08cf81665 | ||
|
|
e06158629e | ||
|
|
3e09961662 | ||
|
|
cc12740c0e | ||
|
|
acb5c0e70f | ||
|
|
6042adebae | ||
|
|
5f54a8691d | ||
|
|
ec13e1bcd3 | ||
|
|
780591d42a | ||
|
|
3aa69823af | ||
|
|
2884428b62 | ||
|
|
fe7b2b9d4f | ||
|
|
44a914e40f | ||
|
|
e07f45fff4 | ||
|
|
3adb7043e8 | ||
|
|
e8779295ee | ||
|
|
7dcd2d6ab6 | ||
|
|
b6c2915f24 | ||
|
|
fa758d6bf5 | ||
|
|
fa9426c749 | ||
|
|
0ecca91dea | ||
|
|
f669a4f3bf | ||
|
|
3275c814bd | ||
|
|
9a180036a5 | ||
|
|
93e7ab52b7 | ||
|
|
facb3b681d | ||
|
|
b67694b2ab | ||
|
|
6c5c8e1c9b | ||
|
|
cb0fc786c7 | ||
|
|
5ef09a102c | ||
|
|
fe7eabd56f | ||
|
|
535adc7a31 | ||
|
|
9c136264de | ||
|
|
34da804aee | ||
|
|
98379cffcb | ||
|
|
9006ddb793 | ||
|
|
dc864762c3 | ||
|
|
dd35bc0722 | ||
|
|
043ec857ab | ||
|
|
f5b17b0b48 | ||
|
|
26dca558c7 | ||
|
|
e10750b35e | ||
|
|
18550039f2 | ||
|
|
0caa483925 | ||
|
|
640b17ec78 | ||
|
|
74a3ba1f0d | ||
|
|
0b7133c4ce | ||
|
|
a367294c23 | ||
|
|
b6004045bd | ||
|
|
cc7e03b0f5 | ||
|
|
1cbd423251 | ||
|
|
437244fe90 | ||
|
|
f7cf24d1f9 | ||
|
|
c3bafacf81 | ||
|
|
57ce0b3d51 | ||
|
|
408ba2e139 | ||
|
|
7632bdba88 | ||
|
|
4b830c1864 | ||
|
|
d6c8767647 | ||
|
|
ec815397a2 |
208
.github/workflows/go-version-update.yml
vendored
Normal file
208
.github/workflows/go-version-update.yml
vendored
Normal file
@@ -0,0 +1,208 @@
|
||||
name: Update Go version
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
schedule:
|
||||
- cron: "0 3 * * 1" # Run weekly on Mondays at 3 AM UTC (1 = Monday)
|
||||
|
||||
permissions:
|
||||
contents: write
|
||||
pull-requests: write
|
||||
|
||||
jobs:
|
||||
update-go-version:
|
||||
name: Check and update Go version
|
||||
if: github.repository == 'github/codeql'
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v5
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Set up Git
|
||||
run: |
|
||||
git config user.name "github-actions[bot]"
|
||||
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
|
||||
|
||||
- name: Fetch latest Go version
|
||||
id: fetch-version
|
||||
run: |
|
||||
LATEST_GO_VERSION=$(curl -s https://go.dev/dl/?mode=json | jq -r '.[0].version')
|
||||
|
||||
if [ -z "$LATEST_GO_VERSION" ] || [ "$LATEST_GO_VERSION" = "null" ]; then
|
||||
echo "Error: Failed to fetch latest Go version from go.dev"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "Latest Go version from go.dev: $LATEST_GO_VERSION"
|
||||
echo "version=$LATEST_GO_VERSION" >> $GITHUB_OUTPUT
|
||||
|
||||
# Extract version numbers (e.g., go1.26.0 -> 1.26.0)
|
||||
LATEST_VERSION_NUM=$(echo $LATEST_GO_VERSION | sed 's/^go//')
|
||||
echo "version_num=$LATEST_VERSION_NUM" >> $GITHUB_OUTPUT
|
||||
|
||||
# Extract major.minor version (e.g., 1.26.0 -> 1.26)
|
||||
LATEST_MAJOR_MINOR=$(echo $LATEST_VERSION_NUM | sed -E 's/^([0-9]+\.[0-9]+).*/\1/')
|
||||
echo "major_minor=$LATEST_MAJOR_MINOR" >> $GITHUB_OUTPUT
|
||||
|
||||
- name: Check current Go version
|
||||
id: current-version
|
||||
run: |
|
||||
CURRENT_VERSION=$(sed -n 's/.*go_sdk\.download(version = \"\([^\"]*\)\".*/\1/p' MODULE.bazel)
|
||||
|
||||
if [ -z "$CURRENT_VERSION" ]; then
|
||||
echo "Error: Could not extract Go version from MODULE.bazel"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "Current Go version in MODULE.bazel: $CURRENT_VERSION"
|
||||
echo "version=$CURRENT_VERSION" >> $GITHUB_OUTPUT
|
||||
|
||||
# Extract major.minor version
|
||||
CURRENT_MAJOR_MINOR=$(echo $CURRENT_VERSION | sed -E 's/^([0-9]+\.[0-9]+).*/\1/')
|
||||
echo "major_minor=$CURRENT_MAJOR_MINOR" >> $GITHUB_OUTPUT
|
||||
|
||||
- name: Compare versions
|
||||
id: compare
|
||||
run: |
|
||||
LATEST="${{ steps.fetch-version.outputs.version_num }}"
|
||||
CURRENT="${{ steps.current-version.outputs.version }}"
|
||||
|
||||
echo "Latest: $LATEST"
|
||||
echo "Current: $CURRENT"
|
||||
|
||||
if [ "$LATEST" = "$CURRENT" ]; then
|
||||
echo "Go version is up to date"
|
||||
echo "needs_update=false" >> $GITHUB_OUTPUT
|
||||
else
|
||||
echo "Go version needs update from $CURRENT to $LATEST"
|
||||
echo "needs_update=true" >> $GITHUB_OUTPUT
|
||||
fi
|
||||
|
||||
- name: Update Go version in files
|
||||
if: steps.compare.outputs.needs_update == 'true'
|
||||
run: |
|
||||
LATEST_VERSION_NUM="${{ steps.fetch-version.outputs.version_num }}"
|
||||
LATEST_MAJOR_MINOR="${{ steps.fetch-version.outputs.major_minor }}"
|
||||
CURRENT_VERSION="${{ steps.current-version.outputs.version }}"
|
||||
CURRENT_MAJOR_MINOR="${{ steps.current-version.outputs.major_minor }}"
|
||||
|
||||
echo "Updating from $CURRENT_VERSION to $LATEST_VERSION_NUM"
|
||||
|
||||
# Escape dots in current version strings for use in sed patterns
|
||||
CURRENT_VERSION_ESCAPED=$(echo "$CURRENT_VERSION" | sed 's/\./\\./g')
|
||||
CURRENT_MAJOR_MINOR_ESCAPED=$(echo "$CURRENT_MAJOR_MINOR" | sed 's/\./\\./g')
|
||||
|
||||
# Update MODULE.bazel
|
||||
sed -i "s/go_sdk\.download(version = \"$CURRENT_VERSION_ESCAPED\")/go_sdk.download(version = \"$LATEST_VERSION_NUM\")/" MODULE.bazel
|
||||
if ! grep -q "go_sdk.download(version = \"$LATEST_VERSION_NUM\")" MODULE.bazel; then
|
||||
echo "Error: Failed to update MODULE.bazel"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Update go/extractor/go.mod
|
||||
if ! sed -i "s/^go $CURRENT_MAJOR_MINOR_ESCAPED\$/go $LATEST_MAJOR_MINOR/" go/extractor/go.mod; then
|
||||
echo "Warning: Failed to update go directive in go.mod"
|
||||
fi
|
||||
if ! sed -i "s/^toolchain go$CURRENT_VERSION_ESCAPED\$/toolchain go$LATEST_VERSION_NUM/" go/extractor/go.mod; then
|
||||
echo "Warning: Failed to update toolchain in go.mod"
|
||||
fi
|
||||
|
||||
# Update go/extractor/autobuilder/build-environment.go
|
||||
if ! sed -i "s/var maxGoVersion = util\.NewSemVer(\"$CURRENT_MAJOR_MINOR_ESCAPED\")/var maxGoVersion = util.NewSemVer(\"$LATEST_MAJOR_MINOR\")/" go/extractor/autobuilder/build-environment.go; then
|
||||
echo "Warning: Failed to update build-environment.go"
|
||||
fi
|
||||
|
||||
# Update go/actions/test/action.yml
|
||||
if ! sed -i "s/default: \"~$CURRENT_VERSION_ESCAPED\"/default: \"~$LATEST_VERSION_NUM\"/" go/actions/test/action.yml; then
|
||||
echo "Warning: Failed to update action.yml"
|
||||
fi
|
||||
|
||||
# Show what changed
|
||||
git diff
|
||||
|
||||
- name: Check for changes
|
||||
id: check-changes
|
||||
if: steps.compare.outputs.needs_update == 'true'
|
||||
run: |
|
||||
if git diff --quiet; then
|
||||
echo "No changes detected"
|
||||
echo "has_changes=false" >> $GITHUB_OUTPUT
|
||||
else
|
||||
echo "Changes detected"
|
||||
echo "has_changes=true" >> $GITHUB_OUTPUT
|
||||
fi
|
||||
|
||||
- name: Check for existing PR
|
||||
if: steps.check-changes.outputs.has_changes == 'true'
|
||||
id: check-pr
|
||||
env:
|
||||
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
run: |
|
||||
BRANCH_NAME="workflow/go-version-update"
|
||||
PR_NUMBER=$(gh pr list --head "$BRANCH_NAME" --state open --json number --jq '.[0].number')
|
||||
|
||||
if [ -n "$PR_NUMBER" ]; then
|
||||
echo "Existing PR found: #$PR_NUMBER"
|
||||
echo "pr_exists=true" >> $GITHUB_OUTPUT
|
||||
echo "pr_number=$PR_NUMBER" >> $GITHUB_OUTPUT
|
||||
else
|
||||
echo "No existing PR found"
|
||||
echo "pr_exists=false" >> $GITHUB_OUTPUT
|
||||
fi
|
||||
|
||||
- name: Commit and push changes
|
||||
if: steps.check-changes.outputs.has_changes == 'true'
|
||||
run: |
|
||||
BRANCH_NAME="workflow/go-version-update"
|
||||
LATEST_VERSION_NUM="${{ steps.fetch-version.outputs.version_num }}"
|
||||
LATEST_MAJOR_MINOR="${{ steps.fetch-version.outputs.major_minor }}"
|
||||
|
||||
# Create or switch to branch
|
||||
git checkout -B "$BRANCH_NAME"
|
||||
|
||||
# Stage and commit changes
|
||||
git add MODULE.bazel go/extractor/go.mod go/extractor/autobuilder/build-environment.go go/actions/test/action.yml
|
||||
git commit -m "Go: Update to $LATEST_VERSION_NUM"
|
||||
|
||||
# Push changes
|
||||
git push --force-with-lease origin "$BRANCH_NAME"
|
||||
|
||||
- name: Create or update PR
|
||||
if: steps.check-changes.outputs.has_changes == 'true'
|
||||
env:
|
||||
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
run: |
|
||||
BRANCH_NAME="workflow/go-version-update"
|
||||
LATEST_VERSION_NUM="${{ steps.fetch-version.outputs.version_num }}"
|
||||
CURRENT_VERSION="${{ steps.current-version.outputs.version }}"
|
||||
|
||||
PR_TITLE="Go: Update to $LATEST_VERSION_NUM"
|
||||
|
||||
PR_BODY=$(cat <<EOF
|
||||
This PR updates Go from $CURRENT_VERSION to $LATEST_VERSION_NUM.
|
||||
|
||||
Updated files:
|
||||
- \`MODULE.bazel\` - go_sdk.download version
|
||||
- \`go/extractor/go.mod\` - go directive and toolchain
|
||||
- \`go/extractor/autobuilder/build-environment.go\` - maxGoVersion (only if MAJOR.MINOR changes)
|
||||
- \`go/actions/test/action.yml\` - default go-test-version
|
||||
|
||||
This PR was automatically created by the [Go version update workflow](https://github.com/${{ github.repository }}/blob/main/.github/workflows/go-version-update.yml).
|
||||
EOF
|
||||
)
|
||||
|
||||
if [ "${{ steps.check-pr.outputs.pr_exists }}" = "true" ]; then
|
||||
echo "Updating existing PR #${{ steps.check-pr.outputs.pr_number }}"
|
||||
gh pr edit "${{ steps.check-pr.outputs.pr_number }}" --title "$PR_TITLE" --body "$PR_BODY"
|
||||
else
|
||||
echo "Creating new PR"
|
||||
gh pr create \
|
||||
--title "$PR_TITLE" \
|
||||
--body "$PR_BODY" \
|
||||
--base main \
|
||||
--head "$BRANCH_NAME" \
|
||||
--label "Go"
|
||||
fi
|
||||
@@ -2,7 +2,7 @@
|
||||
* @github/code-scanning-alert-coverage
|
||||
|
||||
# CodeQL language libraries
|
||||
/actions/ @github/codeql-dynamic
|
||||
/actions/ @github/code-scanning-alert-coverage
|
||||
/cpp/ @github/codeql-c-analysis
|
||||
/csharp/ @github/codeql-csharp
|
||||
/csharp/autobuilder/Semmle.Autobuild.Cpp @github/codeql-c-extractor @github/code-scanning-language-coverage
|
||||
@@ -59,9 +59,5 @@ MODULE.bazel @github/codeql-ci-reviewers
|
||||
/.github/workflows/rust.yml @github/codeql-rust
|
||||
/.github/workflows/swift.yml @github/codeql-swift
|
||||
|
||||
# Misc
|
||||
/misc/scripts/accept-expected-changes-from-ci.py @RasmusWL
|
||||
/misc/scripts/generate-code-scanning-query-list.py @RasmusWL
|
||||
|
||||
# .devcontainer
|
||||
/.devcontainer/ @github/codeql-ci-reviewers
|
||||
|
||||
@@ -273,7 +273,7 @@ use_repo(
|
||||
)
|
||||
|
||||
go_sdk = use_extension("@rules_go//go:extensions.bzl", "go_sdk")
|
||||
go_sdk.download(version = "1.26.0")
|
||||
go_sdk.download(version = "1.26.4")
|
||||
|
||||
go_deps = use_extension("@gazelle//:extensions.bzl", "go_deps")
|
||||
go_deps.from_file(go_mod = "//go/extractor:go.mod")
|
||||
|
||||
@@ -1,3 +1,9 @@
|
||||
## 0.4.37
|
||||
|
||||
### Minor Analysis Improvements
|
||||
|
||||
* The GitHub Actions analysis now recognizes more Bash regex checks that restrict a value to alphanumeric characters, including regexes like `^[0-9a-zA-Z]{40}([0-9a-zA-Z]{24})?$` which check for a SHA-1 or SHA-256 hash. This may reduce false positive results where command output is validated with grouped or optional alphanumeric patterns before being used.
|
||||
|
||||
## 0.4.36
|
||||
|
||||
### Minor Analysis Improvements
|
||||
|
||||
@@ -1,4 +0,0 @@
|
||||
---
|
||||
category: minorAnalysis
|
||||
---
|
||||
* The GitHub Actions analysis now recognizes more Bash regex checks that restrict a value to alphanumeric characters, include regexes like `^[0-9a-zA-Z]{40}([0-9a-zA-Z]{24})?$` which check for a sha1 or sha256 hash. This may reduce false positive results where command output is validated with grouped or optional alphanumeric patterns before being used.
|
||||
@@ -0,0 +1,4 @@
|
||||
---
|
||||
category: fix
|
||||
---
|
||||
* The query `actions/pr-on-self-hosted-runner` was updated to the latest standard runner labels reducing false positive results.
|
||||
5
actions/ql/lib/change-notes/released/0.4.37.md
Normal file
5
actions/ql/lib/change-notes/released/0.4.37.md
Normal file
@@ -0,0 +1,5 @@
|
||||
## 0.4.37
|
||||
|
||||
### Minor Analysis Improvements
|
||||
|
||||
* The GitHub Actions analysis now recognizes more Bash regex checks that restrict a value to alphanumeric characters, including regexes like `^[0-9a-zA-Z]{40}([0-9a-zA-Z]{24})?$` which check for a SHA-1 or SHA-256 hash. This may reduce false positive results where command output is validated with grouped or optional alphanumeric patterns before being used.
|
||||
@@ -1,2 +1,2 @@
|
||||
---
|
||||
lastReleaseVersion: 0.4.36
|
||||
lastReleaseVersion: 0.4.37
|
||||
|
||||
@@ -1920,3 +1920,5 @@ private YamlMappingLikeNode resolveMatrixAccessPath(
|
||||
else result = resolveMatrixAccessPath(newRoot, rest)
|
||||
)
|
||||
}
|
||||
|
||||
class Comment = YamlComment;
|
||||
|
||||
@@ -52,6 +52,12 @@ private module YamlSig implements LibYaml::InputSig {
|
||||
class ParseErrorBase extends LocatableBase, @yaml_error {
|
||||
string getMessage() { yaml_errors(this, result) }
|
||||
}
|
||||
|
||||
class CommentBase extends LocatableBase, @yaml_comment {
|
||||
string getText() { yaml_comments(this, result, _) }
|
||||
|
||||
override string toString() { yaml_comments(this, _, result) }
|
||||
}
|
||||
}
|
||||
|
||||
import LibYaml::Make<YamlSig>
|
||||
|
||||
@@ -2,10 +2,12 @@ import actions
|
||||
|
||||
bindingset[runner]
|
||||
predicate isGithubHostedRunner(string runner) {
|
||||
// list of github hosted repos: https://github.com/actions/runner-images/blob/main/README.md#available-images
|
||||
runner
|
||||
.toLowerCase()
|
||||
.regexpMatch("^(ubuntu-([0-9.]+|latest)|macos-([0-9]+|latest)(-x?large)?|windows-([0-9.]+|latest))$")
|
||||
// The list of github hosted repos:
|
||||
// https://github.com/actions/runner-images/blob/main/README.md#available-images
|
||||
// https://docs.github.com/en/enterprise-cloud@latest/actions/how-tos/write-workflows/choose-where-workflows-run/choose-the-runner-for-a-job#standard-github-hosted-runners-for-public-repositories
|
||||
runner.toLowerCase().regexpMatch("^ubuntu-([0-9.]+|latest|slim)(-arm)?$") or
|
||||
runner.toLowerCase().regexpMatch("^macos-([0-9]+|latest)(-x?large|-intel)?$") or
|
||||
runner.toLowerCase().regexpMatch("^windows-([0-9.]+|latest)(-vs[0-9.]+)?(-arm)?$")
|
||||
}
|
||||
|
||||
bindingset[runner]
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
name: codeql/actions-all
|
||||
version: 0.4.37-dev
|
||||
version: 0.4.38-dev
|
||||
library: true
|
||||
warnOnImplicitThis: true
|
||||
dependencies:
|
||||
|
||||
@@ -1,3 +1,22 @@
|
||||
## 0.6.29
|
||||
|
||||
### Query Metadata Changes
|
||||
|
||||
* Reversed adjustment of the name of `actions/untrusted-checkout/high`, but kept the portion of the previous change for the word "trusted" to "privileged". Added a missing "a" to phrasing in `actions/untrusted-checkout/high` and `actions/untrusted-checkout/medium`.
|
||||
|
||||
### Major Analysis Improvements
|
||||
|
||||
* Adjusted `actions/untrusted-checkout/critical` to align more with other untrusted resource queries, where the alert location is the location where the artifact is obtained from (the checkout point). This aligns with the other 2 related queries. This will cause the same alerts to re-open for closed alerts of this query.
|
||||
|
||||
### Minor Analysis Improvements
|
||||
|
||||
* Altered the alert message for clarity for queries: `actions/untrusted-checkout/critical`, `actions/untrusted-checkout/high`.
|
||||
* The `actions/unpinned-tag` query now recognizes 64-character SHA-256 commit hashes as properly pinned references, in addition to 40-character SHA-1 hashes.
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* Adjusted (minor) help file descriptions for queries: `actions/untrusted-checkout/critical`, `actions/untrusted-checkout/high`, `actions/untrusted-checkout/medium`. Clarified wording on a minor point, added one more listed resource and added one more recommendation for things to check.
|
||||
|
||||
## 0.6.28
|
||||
|
||||
### Query Metadata Changes
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/**
|
||||
* @name Checkout of untrusted code in a trusted context
|
||||
* @description Privileged workflows have read/write access to the base repository and access to secrets.
|
||||
* By explicitly checking out and running the build script from a fork the untrusted code is running in an environment
|
||||
* that is able to push to the base repository and to access secrets.
|
||||
* @name Checkout of untrusted code in a non-privileged context
|
||||
* @description Checking out and running the build script from a fork executes untrusted code. Even in a
|
||||
* non-privileged workflow, this can be abused, for example to compromise self-hosted runners
|
||||
* or to poison caches and artifacts that are later consumed by privileged workflows.
|
||||
* @kind problem
|
||||
* @problem.severity warning
|
||||
* @precision medium
|
||||
@@ -20,4 +20,4 @@ from PRHeadCheckoutStep checkout
|
||||
where
|
||||
// the checkout occurs in a non-privileged context
|
||||
inNonPrivilegedContext(checkout)
|
||||
select checkout, "Potential unsafe checkout of untrusted pull request on privileged workflow."
|
||||
select checkout, "Potential unsafe checkout of untrusted pull request on non-privileged workflow."
|
||||
|
||||
@@ -1,4 +0,0 @@
|
||||
---
|
||||
category: majorAnalysis
|
||||
---
|
||||
* Adjusted `actions/untrusted-checkout/critical` to align more with other untrusted resource queries, where the alert location is the location where the artifact is obtained from (the checkout point). This aligns with the other 2 related queries. This will cause the same alerts to re-open for closed alerts of this query.
|
||||
@@ -1,4 +0,0 @@
|
||||
---
|
||||
category: minorAnalysis
|
||||
---
|
||||
* The `actions/unpinned-tag` query now recognizes 64-character SHA-256 commit hashes as properly pinned references, in addition to 40-character SHA-1 hashes.
|
||||
@@ -1,4 +0,0 @@
|
||||
---
|
||||
category: minorAnalysis
|
||||
---
|
||||
* Altered the alert message for clarity for queries: `actions/untrusted-checkout/critical`, `actions/untrusted-checkout/high`.
|
||||
@@ -1,4 +0,0 @@
|
||||
---
|
||||
category: fix
|
||||
---
|
||||
* Adjusted (minor) help file descriptions for queries: `actions/untrusted-checkout/critical`, `actions/untrusted-checkout/high`, `actions/untrusted-checkout/medium`. Clarified wording on in minor point, added one more listed resource and added one more recommendation for things to check.
|
||||
@@ -1,4 +0,0 @@
|
||||
---
|
||||
category: queryMetadata
|
||||
---
|
||||
* Reversed adjustment of the name of `actions/untrusted-checkout/high`, but kept the portion of the previous change for the word "trusted" to "privileged". Added a missing "a" to phrasing in `actions/untrusted-checkout/high` and `actions/untrusted-checkout/medium`.
|
||||
@@ -0,0 +1,4 @@
|
||||
---
|
||||
category: queryMetadata
|
||||
---
|
||||
* The name, description, and alert message of `actions/untrusted-checkout/medium` have been corrected to describe a non-privileged context.
|
||||
18
actions/ql/src/change-notes/released/0.6.29.md
Normal file
18
actions/ql/src/change-notes/released/0.6.29.md
Normal file
@@ -0,0 +1,18 @@
|
||||
## 0.6.29
|
||||
|
||||
### Query Metadata Changes
|
||||
|
||||
* Reversed adjustment of the name of `actions/untrusted-checkout/high`, but kept the portion of the previous change for the word "trusted" to "privileged". Added a missing "a" to phrasing in `actions/untrusted-checkout/high` and `actions/untrusted-checkout/medium`.
|
||||
|
||||
### Major Analysis Improvements
|
||||
|
||||
* Adjusted `actions/untrusted-checkout/critical` to align more with other untrusted resource queries, where the alert location is the location where the artifact is obtained from (the checkout point). This aligns with the other 2 related queries. This will cause the same alerts to re-open for closed alerts of this query.
|
||||
|
||||
### Minor Analysis Improvements
|
||||
|
||||
* Altered the alert message for clarity for queries: `actions/untrusted-checkout/critical`, `actions/untrusted-checkout/high`.
|
||||
* The `actions/unpinned-tag` query now recognizes 64-character SHA-256 commit hashes as properly pinned references, in addition to 40-character SHA-1 hashes.
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* Adjusted (minor) help file descriptions for queries: `actions/untrusted-checkout/critical`, `actions/untrusted-checkout/high`, `actions/untrusted-checkout/medium`. Clarified wording on a minor point, added one more listed resource and added one more recommendation for things to check.
|
||||
@@ -1,2 +1,2 @@
|
||||
---
|
||||
lastReleaseVersion: 0.6.28
|
||||
lastReleaseVersion: 0.6.29
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
name: codeql/actions-queries
|
||||
version: 0.6.29-dev
|
||||
version: 0.6.30-dev
|
||||
library: false
|
||||
warnOnImplicitThis: true
|
||||
groups: [actions, queries]
|
||||
|
||||
43
actions/ql/test/query-tests/Security/CWE-284/.github/workflows/test3.yml
vendored
Normal file
43
actions/ql/test/query-tests/Security/CWE-284/.github/workflows/test3.yml
vendored
Normal file
@@ -0,0 +1,43 @@
|
||||
name: test
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
|
||||
jobs:
|
||||
test:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os:
|
||||
- ubuntu-latest
|
||||
- ubuntu-24.04
|
||||
- ubuntu-24.04-arm
|
||||
- ubuntu-22.04
|
||||
- ubuntu-22.04-arm
|
||||
- ubuntu-26.04
|
||||
- ubuntu-26.04-arm
|
||||
- ubuntu-slim
|
||||
- macos-26
|
||||
- macos-26-xlarge
|
||||
- macos-26-intel
|
||||
- macos-26-large
|
||||
- macos-latest-large
|
||||
- macos-15-large
|
||||
- macos-15
|
||||
- macos-15-intel
|
||||
- macos-latest
|
||||
- macos-15
|
||||
- macos-15-xlarge
|
||||
- macos-14-large
|
||||
- macos-14
|
||||
- macos-14-xlarge
|
||||
- windows-2025-vs2026
|
||||
- windows-latest
|
||||
- windows-2025
|
||||
- windows-2022
|
||||
- windows-11
|
||||
- windows-11-arm
|
||||
- windows-11-vs2026-arm
|
||||
runs-on: ${{ matrix.os }}
|
||||
steps:
|
||||
- run: cmd
|
||||
@@ -1,10 +1,10 @@
|
||||
| .github/workflows/artifactpoisoning81.yml:11:9:14:6 | Uses Step | Potential unsafe checkout of untrusted pull request on privileged workflow. |
|
||||
| .github/workflows/dependabot2.yml:33:9:38:6 | Uses Step | Potential unsafe checkout of untrusted pull request on privileged workflow. |
|
||||
| .github/workflows/mend.yml:22:9:29:6 | Uses Step | Potential unsafe checkout of untrusted pull request on privileged workflow. |
|
||||
| .github/workflows/poc3.yml:18:7:25:4 | Uses Step | Potential unsafe checkout of untrusted pull request on privileged workflow. |
|
||||
| .github/workflows/poc.yml:30:9:36:6 | Uses Step | Potential unsafe checkout of untrusted pull request on privileged workflow. |
|
||||
| .github/workflows/priv_pull_request_checkout.yml:14:9:20:6 | Uses Step | Potential unsafe checkout of untrusted pull request on privileged workflow. |
|
||||
| .github/workflows/test3.yml:28:9:33:6 | Uses Step | Potential unsafe checkout of untrusted pull request on privileged workflow. |
|
||||
| .github/workflows/test4.yml:18:7:25:4 | Uses Step | Potential unsafe checkout of untrusted pull request on privileged workflow. |
|
||||
| .github/workflows/test8.yml:20:9:26:6 | Uses Step | Potential unsafe checkout of untrusted pull request on privileged workflow. |
|
||||
| .github/workflows/test9.yml:11:9:16:6 | Uses Step | Potential unsafe checkout of untrusted pull request on privileged workflow. |
|
||||
| .github/workflows/artifactpoisoning81.yml:11:9:14:6 | Uses Step | Potential unsafe checkout of untrusted pull request on non-privileged workflow. |
|
||||
| .github/workflows/dependabot2.yml:33:9:38:6 | Uses Step | Potential unsafe checkout of untrusted pull request on non-privileged workflow. |
|
||||
| .github/workflows/mend.yml:22:9:29:6 | Uses Step | Potential unsafe checkout of untrusted pull request on non-privileged workflow. |
|
||||
| .github/workflows/poc3.yml:18:7:25:4 | Uses Step | Potential unsafe checkout of untrusted pull request on non-privileged workflow. |
|
||||
| .github/workflows/poc.yml:30:9:36:6 | Uses Step | Potential unsafe checkout of untrusted pull request on non-privileged workflow. |
|
||||
| .github/workflows/priv_pull_request_checkout.yml:14:9:20:6 | Uses Step | Potential unsafe checkout of untrusted pull request on non-privileged workflow. |
|
||||
| .github/workflows/test3.yml:28:9:33:6 | Uses Step | Potential unsafe checkout of untrusted pull request on non-privileged workflow. |
|
||||
| .github/workflows/test4.yml:18:7:25:4 | Uses Step | Potential unsafe checkout of untrusted pull request on non-privileged workflow. |
|
||||
| .github/workflows/test8.yml:20:9:26:6 | Uses Step | Potential unsafe checkout of untrusted pull request on non-privileged workflow. |
|
||||
| .github/workflows/test9.yml:11:9:16:6 | Uses Step | Potential unsafe checkout of untrusted pull request on non-privileged workflow. |
|
||||
|
||||
@@ -11,10 +11,6 @@
|
||||
"java/ql/lib/semmle/code/java/dataflow/internal/rangeanalysis/SignAnalysisCommon.qll",
|
||||
"csharp/ql/lib/semmle/code/csharp/dataflow/internal/rangeanalysis/SignAnalysisCommon.qll"
|
||||
],
|
||||
"Bound Java/C#": [
|
||||
"java/ql/lib/semmle/code/java/dataflow/Bound.qll",
|
||||
"csharp/ql/lib/semmle/code/csharp/dataflow/Bound.qll"
|
||||
],
|
||||
"ModulusAnalysis Java/C#": [
|
||||
"java/ql/lib/semmle/code/java/dataflow/ModulusAnalysis.qll",
|
||||
"csharp/ql/lib/semmle/code/csharp/dataflow/ModulusAnalysis.qll"
|
||||
|
||||
2578
cpp/downgrades/0853f43dc8c08deecb473c54a2b70da8597f1ab5/old.dbscheme
Normal file
2578
cpp/downgrades/0853f43dc8c08deecb473c54a2b70da8597f1ab5/old.dbscheme
Normal file
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,2 @@
|
||||
description: Fix NameQualifier inconsistency
|
||||
compatibility: full
|
||||
@@ -1,3 +1,19 @@
|
||||
## 10.2.0
|
||||
|
||||
### Deprecated APIs
|
||||
|
||||
* The `UsingAliasTypedefType` class has been deprecated. Use `TypeAliasType` instead.
|
||||
|
||||
### New Features
|
||||
|
||||
* Added a `getOriginalTemplate` predicate to `TemplateClass`, `TemplateFunction`, `TemplateVariable`, and `AliasTemplateType`, which yields the class member template the template was generated from. The predicates only have results for templates that are members of class template instantiations.
|
||||
* Added `AliasTemplateType` and `AliasTemplateInstantiationType` classes, representing C++ alias templates and their instantiations.
|
||||
|
||||
### Minor Analysis Improvements
|
||||
|
||||
* Added flow source models for `scanf_s` and related functions.
|
||||
* Added a `Call` column to `LocalFlowSourceFunction::hasLocalFlowSource` and `RemoteFlowSourceFunction::hasRemoteFlowSource`. The old predicates without a `Call` column continue to be supported.
|
||||
|
||||
## 10.1.1
|
||||
|
||||
### Minor Analysis Improvements
|
||||
|
||||
@@ -1,5 +0,0 @@
|
||||
---
|
||||
category: minorAnalysis
|
||||
---
|
||||
* Added flow source models for `scanf_s` and related functions.
|
||||
* Added a `Call` column to `LocalFlowSourceFunction::hasLocalFlowSource` and `RemoteFlowSourceFunction::hasRemoteFlowSource`. The old predicates without a `Call` column continue to be supported.
|
||||
@@ -1,4 +0,0 @@
|
||||
---
|
||||
category: feature
|
||||
---
|
||||
* Added `AliasTemplateType` and `AliasTemplateInstantiationType` classes, representing C++ alias templates and their instantiations.
|
||||
@@ -1,4 +0,0 @@
|
||||
---
|
||||
category: deprecated
|
||||
---
|
||||
* The `UsingAliasTypedefType` class has been deprecated. Use `TypeAliasType` instead.
|
||||
@@ -1,4 +0,0 @@
|
||||
---
|
||||
category: feature
|
||||
---
|
||||
* Added a `getOriginalTemplate` predicate to `TemplateClass`, `TemplateFunction`, `TemplateVariable`, and `AliasTemplateType`, which yields the class member template the template was generated from. The predicates only have results for templates that are members of class template instantiations.
|
||||
15
cpp/ql/lib/change-notes/released/10.2.0.md
Normal file
15
cpp/ql/lib/change-notes/released/10.2.0.md
Normal file
@@ -0,0 +1,15 @@
|
||||
## 10.2.0
|
||||
|
||||
### Deprecated APIs
|
||||
|
||||
* The `UsingAliasTypedefType` class has been deprecated. Use `TypeAliasType` instead.
|
||||
|
||||
### New Features
|
||||
|
||||
* Added a `getOriginalTemplate` predicate to `TemplateClass`, `TemplateFunction`, `TemplateVariable`, and `AliasTemplateType`, which yields the class member template the template was generated from. The predicates only have results for templates that are members of class template instantiations.
|
||||
* Added `AliasTemplateType` and `AliasTemplateInstantiationType` classes, representing C++ alias templates and their instantiations.
|
||||
|
||||
### Minor Analysis Improvements
|
||||
|
||||
* Added flow source models for `scanf_s` and related functions.
|
||||
* Added a `Call` column to `LocalFlowSourceFunction::hasLocalFlowSource` and `RemoteFlowSourceFunction::hasRemoteFlowSource`. The old predicates without a `Call` column continue to be supported.
|
||||
@@ -1,2 +1,2 @@
|
||||
---
|
||||
lastReleaseVersion: 10.1.1
|
||||
lastReleaseVersion: 10.2.0
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
name: codeql/cpp-all
|
||||
version: 10.1.2-dev
|
||||
version: 10.2.1-dev
|
||||
groups: cpp
|
||||
dbscheme: semmlecode.cpp.dbscheme
|
||||
extractor: cpp
|
||||
|
||||
@@ -1071,7 +1071,7 @@ class NullPointerType extends BuiltInType {
|
||||
* const float fa[40];
|
||||
* ```
|
||||
*/
|
||||
class DerivedType extends Type, @derivedtype {
|
||||
class DerivedType extends Type, NameQualifyingElement, @derivedtype {
|
||||
override string toString() { result = this.getName() }
|
||||
|
||||
override string getName() { derivedtypes(underlyingElement(this), result, _, _) }
|
||||
|
||||
@@ -276,6 +276,45 @@ private predicate isClassConstructedFrom(Class c, Class templateClass) {
|
||||
not c.isConstructedFrom(_) and c = templateClass
|
||||
}
|
||||
|
||||
/** Gets the fully templated version of `c`. */
|
||||
private Class getFullyTemplatedClassOld(Class c) {
|
||||
not c.isFromUninstantiatedTemplate(_) and
|
||||
isClassConstructedFrom(c, result)
|
||||
}
|
||||
|
||||
private TemplateClass getOriginalClassTemplate(TemplateClass tc) {
|
||||
result = tc.getOriginalTemplate()
|
||||
or
|
||||
not exists(tc.getOriginalTemplate()) and
|
||||
result = tc
|
||||
}
|
||||
|
||||
/** Gets the fully templated version of `c`. */
|
||||
private Class getFullyTemplatedClassNew(Class c) {
|
||||
not c.isFromUninstantiatedTemplate(_) and
|
||||
exists(Class mid |
|
||||
c.isConstructedFrom(mid)
|
||||
or
|
||||
not c.isConstructedFrom(_) and c = mid
|
||||
|
|
||||
result = getOriginalClassTemplate(mid)
|
||||
or
|
||||
not mid instanceof TemplateClass and mid = result
|
||||
)
|
||||
}
|
||||
|
||||
/** Gets the fully templated version of `c`. */
|
||||
private Class getFullyTemplatedClass(Class c) {
|
||||
// The `Class::getOriginalTemplate` predicate was introduced in CodeQL
|
||||
// version 2.25.6 and the upgrade script leaves the
|
||||
// `class_template_generated_from` extensionals empty if the database
|
||||
// was generated with an older extractor. So we use the old implementation
|
||||
// if the `class_template_generated_from` extensional is empty.
|
||||
if class_template_generated_from(_, _)
|
||||
then result = getFullyTemplatedClassNew(c)
|
||||
else result = getFullyTemplatedClassOld(c)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if `f` is an instantiation of a function template `templateFunc`, or
|
||||
* holds with `f = templateFunc` if `f` is not an instantiation of any function
|
||||
@@ -292,7 +331,7 @@ private predicate isFunctionConstructedFrom(Function f, Function templateFunc) {
|
||||
}
|
||||
|
||||
/** Gets the fully templated version of `f`. */
|
||||
Function getFullyTemplatedFunction(Function f) {
|
||||
private Function getFullyTemplatedFunctionOld(Function f) {
|
||||
not f.isFromUninstantiatedTemplate(_) and
|
||||
(
|
||||
exists(Class c, Class templateClass, int i |
|
||||
@@ -306,13 +345,46 @@ Function getFullyTemplatedFunction(Function f) {
|
||||
)
|
||||
}
|
||||
|
||||
private TemplateFunction getOriginalFunctionTemplate(TemplateFunction tf) {
|
||||
result = tf.getOriginalTemplate()
|
||||
or
|
||||
not exists(tf.getOriginalTemplate()) and
|
||||
result = tf
|
||||
}
|
||||
|
||||
/** Gets the fully templated version of `f`. */
|
||||
private Function getFullyTemplatedFunctionNew(Function f) {
|
||||
not f.isFromUninstantiatedTemplate(_) and
|
||||
exists(Function mid |
|
||||
f.isConstructedFrom(mid)
|
||||
or
|
||||
not f.isConstructedFrom(_) and f = mid
|
||||
|
|
||||
result = getOriginalFunctionTemplate(mid)
|
||||
or
|
||||
not mid instanceof TemplateFunction and mid = result
|
||||
)
|
||||
}
|
||||
|
||||
/** Gets the fully templated version of `f`. */
|
||||
Function getFullyTemplatedFunction(Function f) {
|
||||
// The `Function::getOriginalTemplate` predicate was introduced in CodeQL
|
||||
// version 2.25.6 and the upgrade script leaves the
|
||||
// `function_template_generated_from` extensionals empty if the database
|
||||
// was generated with an older extractor. So we use the old implementation
|
||||
// if the `function_template_generated_from` extensional is empty.
|
||||
if function_template_generated_from(_, _)
|
||||
then result = getFullyTemplatedFunctionNew(f)
|
||||
else result = getFullyTemplatedFunctionOld(f)
|
||||
}
|
||||
|
||||
/** Prefixes `const` to `s` if `t` is const, or returns `s` otherwise. */
|
||||
bindingset[s, t]
|
||||
private string withConst(string s, Type t) {
|
||||
if t.isConst() then result = "const " + s else result = s
|
||||
}
|
||||
|
||||
/** Prefixes `volatile` to `s` if `t` is const, or returns `s` otherwise. */
|
||||
/** Prefixes `volatile` to `s` if `t` is volatile, or returns `s` otherwise. */
|
||||
bindingset[s, t]
|
||||
private string withVolatile(string s, Type t) {
|
||||
if t.isVolatile() then result = "volatile " + s else result = s
|
||||
@@ -490,7 +562,7 @@ pragma[nomagic]
|
||||
private string getTypeNameWithoutClassTemplates(Function f, int n, int remaining) {
|
||||
// If there is a declaring type then we start by expanding the function templates
|
||||
exists(Class template |
|
||||
isClassConstructedFrom(f.getDeclaringType(), template) and
|
||||
template = getFullyTemplatedClass(f.getDeclaringType()) and
|
||||
remaining = getNumberOfSupportedClassTemplateArguments(template) and
|
||||
result = getTypeNameWithoutFunctionTemplates(f, n, 0)
|
||||
)
|
||||
@@ -502,7 +574,7 @@ private string getTypeNameWithoutClassTemplates(Function f, int n, int remaining
|
||||
or
|
||||
exists(string mid, TypeTemplateParameter tp, Class template |
|
||||
mid = getTypeNameWithoutClassTemplates(f, n, remaining + 1) and
|
||||
isClassConstructedFrom(f.getDeclaringType(), template) and
|
||||
template = getFullyTemplatedClass(f.getDeclaringType()) and
|
||||
tp = getSupportedClassTemplateArgument(template, remaining)
|
||||
|
|
||||
result = mid.replaceAll(tp.getName(), "class:" + remaining.toString())
|
||||
|
||||
@@ -1430,7 +1430,8 @@ specialnamequalifyingelements(
|
||||
@namequalifyingelement = @namespace
|
||||
| @specialnamequalifyingelement
|
||||
| @usertype
|
||||
| @decltype;
|
||||
| @decltype
|
||||
| @derivedtype;
|
||||
|
||||
namequalifiers(
|
||||
unique int id: @namequalifier,
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,2 @@
|
||||
description: Fix NameQualifier inconsistency
|
||||
compatibility: full
|
||||
@@ -1,3 +1,7 @@
|
||||
## 1.6.4
|
||||
|
||||
No user-facing changes.
|
||||
|
||||
## 1.6.3
|
||||
|
||||
### Minor Analysis Improvements
|
||||
|
||||
3
cpp/ql/src/change-notes/released/1.6.4.md
Normal file
3
cpp/ql/src/change-notes/released/1.6.4.md
Normal file
@@ -0,0 +1,3 @@
|
||||
## 1.6.4
|
||||
|
||||
No user-facing changes.
|
||||
@@ -1,2 +1,2 @@
|
||||
---
|
||||
lastReleaseVersion: 1.6.3
|
||||
lastReleaseVersion: 1.6.4
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
name: codeql/cpp-queries
|
||||
version: 1.6.4-dev
|
||||
version: 1.6.5-dev
|
||||
groups:
|
||||
- cpp
|
||||
- queries
|
||||
|
||||
@@ -51,13 +51,16 @@ models
|
||||
| 50 | Summary: ; ; false; ymlStepGenerated; ; ; Argument[0]; ReturnValue; taint; df-generated |
|
||||
| 51 | Summary: ; ; false; ymlStepManual; ; ; Argument[0]; ReturnValue; taint; manual |
|
||||
| 52 | Summary: ; ; false; ymlStepManual_with_body; ; ; Argument[0]; ReturnValue; taint; manual |
|
||||
| 53 | Summary: Azure::Core::IO; BodyStream; true; Read; ; ; Argument[-1]; Argument[*0]; taint; manual |
|
||||
| 54 | Summary: Azure::Core::IO; BodyStream; true; ReadToCount; ; ; Argument[-1]; Argument[*0]; taint; manual |
|
||||
| 55 | Summary: Azure::Core::IO; BodyStream; true; ReadToEnd; ; ; Argument[-1]; ReturnValue.Element; taint; manual |
|
||||
| 56 | Summary: Azure; Nullable; true; Value; ; ; Argument[-1]; ReturnValue[*]; taint; manual |
|
||||
| 57 | Summary: boost::asio; ; false; buffer; ; ; Argument[*0]; ReturnValue; taint; manual |
|
||||
| 53 | Summary: ; TemplateClass1; true; templateFunction2<U,V>; (U,V); ; Argument[1]; ReturnValue; value; manual |
|
||||
| 54 | Summary: ; TemplateClass1<T>; false; templateFunction<U>; (T,U); ; Argument[0]; ReturnValue; value; manual |
|
||||
| 55 | Summary: ; TemplateClass2<T,U>; true; function; (U,T); ; Argument[1]; ReturnValue; value; manual |
|
||||
| 56 | Summary: Azure::Core::IO; BodyStream; true; Read; ; ; Argument[-1]; Argument[*0]; taint; manual |
|
||||
| 57 | Summary: Azure::Core::IO; BodyStream; true; ReadToCount; ; ; Argument[-1]; Argument[*0]; taint; manual |
|
||||
| 58 | Summary: Azure::Core::IO; BodyStream; true; ReadToEnd; ; ; Argument[-1]; ReturnValue.Element; taint; manual |
|
||||
| 59 | Summary: Azure; Nullable; true; Value; ; ; Argument[-1]; ReturnValue[*]; taint; manual |
|
||||
| 60 | Summary: boost::asio; ; false; buffer; ; ; Argument[*0]; ReturnValue; taint; manual |
|
||||
edges
|
||||
| asio_streams.cpp:56:18:56:23 | [summary param] *0 in buffer | asio_streams.cpp:56:18:56:23 | [summary] to write: ReturnValue in buffer | provenance | MaD:57 |
|
||||
| asio_streams.cpp:56:18:56:23 | [summary param] *0 in buffer | asio_streams.cpp:56:18:56:23 | [summary] to write: ReturnValue in buffer | provenance | MaD:60 |
|
||||
| asio_streams.cpp:87:34:87:44 | read_until output argument | asio_streams.cpp:91:7:91:17 | recv_buffer | provenance | Src:MaD:32 |
|
||||
| asio_streams.cpp:87:34:87:44 | read_until output argument | asio_streams.cpp:93:29:93:39 | *recv_buffer | provenance | Src:MaD:32 Sink:MaD:2 |
|
||||
| asio_streams.cpp:97:37:97:44 | call to source | asio_streams.cpp:98:7:98:14 | send_str | provenance | TaintFunction |
|
||||
@@ -66,24 +69,24 @@ edges
|
||||
| asio_streams.cpp:100:44:100:62 | call to buffer | asio_streams.cpp:101:7:101:17 | send_buffer | provenance | |
|
||||
| asio_streams.cpp:100:44:100:62 | call to buffer | asio_streams.cpp:103:29:103:39 | *send_buffer | provenance | Sink:MaD:2 |
|
||||
| asio_streams.cpp:100:64:100:71 | *send_str | asio_streams.cpp:56:18:56:23 | [summary param] *0 in buffer | provenance | |
|
||||
| asio_streams.cpp:100:64:100:71 | *send_str | asio_streams.cpp:100:44:100:62 | call to buffer | provenance | MaD:57 |
|
||||
| azure.cpp:62:10:62:14 | [summary param] this in Value | azure.cpp:62:10:62:14 | [summary] to write: ReturnValue[*] in Value | provenance | MaD:56 |
|
||||
| azure.cpp:113:16:113:19 | [summary param] this in Read | azure.cpp:113:16:113:19 | [summary param] *0 in Read [Return] | provenance | MaD:53 |
|
||||
| azure.cpp:114:16:114:26 | [summary param] this in ReadToCount | azure.cpp:114:16:114:26 | [summary param] *0 in ReadToCount [Return] | provenance | MaD:54 |
|
||||
| azure.cpp:115:30:115:38 | [summary param] this in ReadToEnd | azure.cpp:115:30:115:38 | [summary] to write: ReturnValue.Element in ReadToEnd | provenance | MaD:55 |
|
||||
| asio_streams.cpp:100:64:100:71 | *send_str | asio_streams.cpp:100:44:100:62 | call to buffer | provenance | MaD:60 |
|
||||
| azure.cpp:62:10:62:14 | [summary param] this in Value | azure.cpp:62:10:62:14 | [summary] to write: ReturnValue[*] in Value | provenance | MaD:59 |
|
||||
| azure.cpp:113:16:113:19 | [summary param] this in Read | azure.cpp:113:16:113:19 | [summary param] *0 in Read [Return] | provenance | MaD:56 |
|
||||
| azure.cpp:114:16:114:26 | [summary param] this in ReadToCount | azure.cpp:114:16:114:26 | [summary param] *0 in ReadToCount [Return] | provenance | MaD:57 |
|
||||
| azure.cpp:115:30:115:38 | [summary param] this in ReadToEnd | azure.cpp:115:30:115:38 | [summary] to write: ReturnValue.Element in ReadToEnd | provenance | MaD:58 |
|
||||
| azure.cpp:115:30:115:38 | [summary] to write: ReturnValue.Element in ReadToEnd | azure.cpp:115:30:115:38 | [summary] to write: ReturnValue in ReadToEnd [element] | provenance | |
|
||||
| azure.cpp:253:48:253:60 | *call to GetBodyStream | azure.cpp:253:48:253:60 | *call to GetBodyStream | provenance | Src:MaD:29 |
|
||||
| azure.cpp:253:48:253:60 | *call to GetBodyStream | azure.cpp:257:5:257:8 | *resp | provenance | |
|
||||
| azure.cpp:253:48:253:60 | *call to GetBodyStream | azure.cpp:262:5:262:8 | *resp | provenance | |
|
||||
| azure.cpp:253:48:253:60 | *call to GetBodyStream | azure.cpp:266:38:266:41 | *resp | provenance | |
|
||||
| azure.cpp:257:5:257:8 | *resp | azure.cpp:113:16:113:19 | [summary param] this in Read | provenance | |
|
||||
| azure.cpp:257:5:257:8 | *resp | azure.cpp:257:16:257:21 | Read output argument | provenance | MaD:53 |
|
||||
| azure.cpp:257:5:257:8 | *resp | azure.cpp:257:16:257:21 | Read output argument | provenance | MaD:56 |
|
||||
| azure.cpp:257:16:257:21 | Read output argument | azure.cpp:258:10:258:16 | * ... | provenance | |
|
||||
| azure.cpp:262:5:262:8 | *resp | azure.cpp:114:16:114:26 | [summary param] this in ReadToCount | provenance | |
|
||||
| azure.cpp:262:5:262:8 | *resp | azure.cpp:262:23:262:28 | ReadToCount output argument | provenance | MaD:54 |
|
||||
| azure.cpp:262:5:262:8 | *resp | azure.cpp:262:23:262:28 | ReadToCount output argument | provenance | MaD:57 |
|
||||
| azure.cpp:262:23:262:28 | ReadToCount output argument | azure.cpp:263:10:263:16 | * ... | provenance | |
|
||||
| azure.cpp:266:38:266:41 | *resp | azure.cpp:115:30:115:38 | [summary param] this in ReadToEnd | provenance | |
|
||||
| azure.cpp:266:38:266:41 | *resp | azure.cpp:266:44:266:52 | call to ReadToEnd [element] | provenance | MaD:55 |
|
||||
| azure.cpp:266:38:266:41 | *resp | azure.cpp:266:44:266:52 | call to ReadToEnd [element] | provenance | MaD:58 |
|
||||
| azure.cpp:266:44:266:52 | call to ReadToEnd [element] | azure.cpp:266:44:266:52 | call to ReadToEnd [element] | provenance | |
|
||||
| azure.cpp:266:44:266:52 | call to ReadToEnd [element] | azure.cpp:267:10:267:12 | vec [element] | provenance | |
|
||||
| azure.cpp:267:10:267:12 | vec [element] | azure.cpp:267:10:267:12 | vec | provenance | |
|
||||
@@ -100,11 +103,11 @@ edges
|
||||
| azure.cpp:281:68:281:84 | *call to ExtractBodyStream | azure.cpp:281:68:281:84 | *call to ExtractBodyStream | provenance | Src:MaD:26 |
|
||||
| azure.cpp:281:68:281:84 | *call to ExtractBodyStream | azure.cpp:282:21:282:23 | *call to get | provenance | |
|
||||
| azure.cpp:282:21:282:23 | *call to get | azure.cpp:115:30:115:38 | [summary param] this in ReadToEnd | provenance | |
|
||||
| azure.cpp:282:21:282:23 | *call to get | azure.cpp:282:28:282:36 | call to ReadToEnd [element] | provenance | MaD:55 |
|
||||
| azure.cpp:282:21:282:23 | *call to get | azure.cpp:282:28:282:36 | call to ReadToEnd [element] | provenance | MaD:58 |
|
||||
| azure.cpp:282:28:282:36 | call to ReadToEnd [element] | azure.cpp:282:10:282:38 | call to ReadToEnd | provenance | |
|
||||
| azure.cpp:282:28:282:36 | call to ReadToEnd [element] | azure.cpp:282:28:282:36 | call to ReadToEnd [element] | provenance | |
|
||||
| azure.cpp:289:24:289:56 | call to GetHeader | azure.cpp:62:10:62:14 | [summary param] this in Value | provenance | |
|
||||
| azure.cpp:289:24:289:56 | call to GetHeader | azure.cpp:289:63:289:65 | call to Value | provenance | MaD:56 |
|
||||
| azure.cpp:289:24:289:56 | call to GetHeader | azure.cpp:289:63:289:65 | call to Value | provenance | MaD:59 |
|
||||
| azure.cpp:289:32:289:40 | call to GetHeader | azure.cpp:289:24:289:56 | call to GetHeader | provenance | |
|
||||
| azure.cpp:289:32:289:40 | call to GetHeader | azure.cpp:289:32:289:40 | call to GetHeader | provenance | Src:MaD:30 |
|
||||
| azure.cpp:289:63:289:65 | call to Value | azure.cpp:289:63:289:65 | call to Value | provenance | |
|
||||
@@ -180,6 +183,39 @@ edges
|
||||
| test.cpp:118:11:118:42 | call to callWithNonTypeTemplate | test.cpp:119:10:119:11 | y2 | provenance | Sink:MaD:1 |
|
||||
| test.cpp:118:44:118:44 | *x | test.cpp:111:3:111:25 | [summary param] *0 in callWithNonTypeTemplate | provenance | |
|
||||
| test.cpp:118:44:118:44 | *x | test.cpp:118:11:118:42 | call to callWithNonTypeTemplate | provenance | MaD:48 |
|
||||
| test.cpp:125:5:125:20 | [summary param] 0 in templateFunction | test.cpp:125:5:125:20 | [summary] to write: ReturnValue in templateFunction | provenance | MaD:54 |
|
||||
| test.cpp:128:5:128:21 | [summary param] 1 in templateFunction2 | test.cpp:128:5:128:21 | [summary] to write: ReturnValue in templateFunction2 | provenance | MaD:53 |
|
||||
| test.cpp:133:10:133:18 | call to ymlSource | test.cpp:133:10:133:18 | call to ymlSource | provenance | Src:MaD:25 |
|
||||
| test.cpp:133:10:133:18 | call to ymlSource | test.cpp:134:45:134:45 | x | provenance | |
|
||||
| test.cpp:134:13:134:43 | call to templateFunction | test.cpp:134:13:134:43 | call to templateFunction | provenance | |
|
||||
| test.cpp:134:13:134:43 | call to templateFunction | test.cpp:135:10:135:10 | y | provenance | Sink:MaD:1 |
|
||||
| test.cpp:134:45:134:45 | x | test.cpp:125:5:125:20 | [summary param] 0 in templateFunction | provenance | |
|
||||
| test.cpp:134:45:134:45 | x | test.cpp:134:13:134:43 | call to templateFunction | provenance | MaD:54 |
|
||||
| test.cpp:140:4:140:11 | [summary param] 1 in function | test.cpp:140:4:140:11 | [summary] to write: ReturnValue in function | provenance | MaD:55 |
|
||||
| test.cpp:140:4:140:11 | [summary param] 1 in function | test.cpp:140:4:140:11 | [summary] to write: ReturnValue in function | provenance | MaD:55 |
|
||||
| test.cpp:146:10:146:18 | call to ymlSource | test.cpp:146:10:146:18 | call to ymlSource | provenance | Src:MaD:25 |
|
||||
| test.cpp:146:10:146:18 | call to ymlSource | test.cpp:148:26:148:26 | x | provenance | |
|
||||
| test.cpp:148:10:148:27 | call to function | test.cpp:148:10:148:27 | call to function | provenance | |
|
||||
| test.cpp:148:10:148:27 | call to function | test.cpp:149:10:149:10 | z | provenance | Sink:MaD:1 |
|
||||
| test.cpp:148:26:148:26 | x | test.cpp:140:4:140:11 | [summary param] 1 in function | provenance | |
|
||||
| test.cpp:148:26:148:26 | x | test.cpp:148:10:148:27 | call to function | provenance | MaD:55 |
|
||||
| test.cpp:155:10:155:18 | call to ymlSource | test.cpp:155:10:155:18 | call to ymlSource | provenance | Src:MaD:25 |
|
||||
| test.cpp:155:10:155:18 | call to ymlSource | test.cpp:157:26:157:26 | x | provenance | |
|
||||
| test.cpp:157:13:157:20 | call to function | test.cpp:157:13:157:20 | call to function | provenance | |
|
||||
| test.cpp:157:13:157:20 | call to function | test.cpp:158:10:158:10 | z | provenance | Sink:MaD:1 |
|
||||
| test.cpp:157:26:157:26 | x | test.cpp:140:4:140:11 | [summary param] 1 in function | provenance | |
|
||||
| test.cpp:157:26:157:26 | x | test.cpp:157:13:157:20 | call to function | provenance | MaD:55 |
|
||||
| test.cpp:164:34:164:34 | x | test.cpp:165:69:165:69 | x | provenance | |
|
||||
| test.cpp:165:12:165:64 | call to templateFunction2 | test.cpp:164:7:164:7 | *templateFunction3 | provenance | |
|
||||
| test.cpp:165:12:165:64 | call to templateFunction2 | test.cpp:165:12:165:64 | call to templateFunction2 | provenance | |
|
||||
| test.cpp:165:69:165:69 | x | test.cpp:128:5:128:21 | [summary param] 1 in templateFunction2 | provenance | |
|
||||
| test.cpp:165:69:165:69 | x | test.cpp:165:12:165:64 | call to templateFunction2 | provenance | MaD:53 |
|
||||
| test.cpp:170:10:170:18 | call to ymlSource | test.cpp:170:10:170:18 | call to ymlSource | provenance | Src:MaD:25 |
|
||||
| test.cpp:170:10:170:18 | call to ymlSource | test.cpp:172:51:172:51 | x | provenance | |
|
||||
| test.cpp:172:13:172:44 | call to templateFunction3 | test.cpp:172:13:172:44 | call to templateFunction3 | provenance | |
|
||||
| test.cpp:172:13:172:44 | call to templateFunction3 | test.cpp:173:10:173:10 | y | provenance | Sink:MaD:1 |
|
||||
| test.cpp:172:51:172:51 | x | test.cpp:164:34:164:34 | x | provenance | |
|
||||
| test.cpp:172:51:172:51 | x | test.cpp:172:13:172:44 | call to templateFunction3 | provenance | MaD:53 |
|
||||
| windows.cpp:17:8:17:25 | [summary param] *0 in CommandLineToArgvA | windows.cpp:17:8:17:25 | [summary] to write: ReturnValue[**] in CommandLineToArgvA | provenance | MaD:33 |
|
||||
| windows.cpp:22:15:22:29 | *call to GetCommandLineA | windows.cpp:22:15:22:29 | *call to GetCommandLineA | provenance | Src:MaD:3 |
|
||||
| windows.cpp:22:15:22:29 | *call to GetCommandLineA | windows.cpp:24:8:24:11 | * ... | provenance | |
|
||||
@@ -483,6 +519,43 @@ nodes
|
||||
| test.cpp:118:11:118:42 | call to callWithNonTypeTemplate | semmle.label | call to callWithNonTypeTemplate |
|
||||
| test.cpp:118:44:118:44 | *x | semmle.label | *x |
|
||||
| test.cpp:119:10:119:11 | y2 | semmle.label | y2 |
|
||||
| test.cpp:125:5:125:20 | [summary param] 0 in templateFunction | semmle.label | [summary param] 0 in templateFunction |
|
||||
| test.cpp:125:5:125:20 | [summary] to write: ReturnValue in templateFunction | semmle.label | [summary] to write: ReturnValue in templateFunction |
|
||||
| test.cpp:128:5:128:21 | [summary param] 1 in templateFunction2 | semmle.label | [summary param] 1 in templateFunction2 |
|
||||
| test.cpp:128:5:128:21 | [summary] to write: ReturnValue in templateFunction2 | semmle.label | [summary] to write: ReturnValue in templateFunction2 |
|
||||
| test.cpp:133:10:133:18 | call to ymlSource | semmle.label | call to ymlSource |
|
||||
| test.cpp:133:10:133:18 | call to ymlSource | semmle.label | call to ymlSource |
|
||||
| test.cpp:134:13:134:43 | call to templateFunction | semmle.label | call to templateFunction |
|
||||
| test.cpp:134:13:134:43 | call to templateFunction | semmle.label | call to templateFunction |
|
||||
| test.cpp:134:45:134:45 | x | semmle.label | x |
|
||||
| test.cpp:135:10:135:10 | y | semmle.label | y |
|
||||
| test.cpp:140:4:140:11 | [summary param] 1 in function | semmle.label | [summary param] 1 in function |
|
||||
| test.cpp:140:4:140:11 | [summary param] 1 in function | semmle.label | [summary param] 1 in function |
|
||||
| test.cpp:140:4:140:11 | [summary] to write: ReturnValue in function | semmle.label | [summary] to write: ReturnValue in function |
|
||||
| test.cpp:140:4:140:11 | [summary] to write: ReturnValue in function | semmle.label | [summary] to write: ReturnValue in function |
|
||||
| test.cpp:146:10:146:18 | call to ymlSource | semmle.label | call to ymlSource |
|
||||
| test.cpp:146:10:146:18 | call to ymlSource | semmle.label | call to ymlSource |
|
||||
| test.cpp:148:10:148:27 | call to function | semmle.label | call to function |
|
||||
| test.cpp:148:10:148:27 | call to function | semmle.label | call to function |
|
||||
| test.cpp:148:26:148:26 | x | semmle.label | x |
|
||||
| test.cpp:149:10:149:10 | z | semmle.label | z |
|
||||
| test.cpp:155:10:155:18 | call to ymlSource | semmle.label | call to ymlSource |
|
||||
| test.cpp:155:10:155:18 | call to ymlSource | semmle.label | call to ymlSource |
|
||||
| test.cpp:157:13:157:20 | call to function | semmle.label | call to function |
|
||||
| test.cpp:157:13:157:20 | call to function | semmle.label | call to function |
|
||||
| test.cpp:157:26:157:26 | x | semmle.label | x |
|
||||
| test.cpp:158:10:158:10 | z | semmle.label | z |
|
||||
| test.cpp:164:7:164:7 | *templateFunction3 | semmle.label | *templateFunction3 |
|
||||
| test.cpp:164:34:164:34 | x | semmle.label | x |
|
||||
| test.cpp:165:12:165:64 | call to templateFunction2 | semmle.label | call to templateFunction2 |
|
||||
| test.cpp:165:12:165:64 | call to templateFunction2 | semmle.label | call to templateFunction2 |
|
||||
| test.cpp:165:69:165:69 | x | semmle.label | x |
|
||||
| test.cpp:170:10:170:18 | call to ymlSource | semmle.label | call to ymlSource |
|
||||
| test.cpp:170:10:170:18 | call to ymlSource | semmle.label | call to ymlSource |
|
||||
| test.cpp:172:13:172:44 | call to templateFunction3 | semmle.label | call to templateFunction3 |
|
||||
| test.cpp:172:13:172:44 | call to templateFunction3 | semmle.label | call to templateFunction3 |
|
||||
| test.cpp:172:51:172:51 | x | semmle.label | x |
|
||||
| test.cpp:173:10:173:10 | y | semmle.label | y |
|
||||
| windows.cpp:17:8:17:25 | [summary param] *0 in CommandLineToArgvA | semmle.label | [summary param] *0 in CommandLineToArgvA |
|
||||
| windows.cpp:17:8:17:25 | [summary] to write: ReturnValue[**] in CommandLineToArgvA | semmle.label | [summary] to write: ReturnValue[**] in CommandLineToArgvA |
|
||||
| windows.cpp:22:15:22:29 | *call to GetCommandLineA | semmle.label | *call to GetCommandLineA |
|
||||
@@ -688,6 +761,11 @@ subpaths
|
||||
| test.cpp:25:35:25:35 | x | test.cpp:6:5:6:27 | [summary param] 0 in ymlStepManual_with_body | test.cpp:6:5:6:27 | [summary] to write: ReturnValue in ymlStepManual_with_body | test.cpp:25:11:25:33 | call to ymlStepManual_with_body |
|
||||
| test.cpp:32:41:32:41 | x | test.cpp:7:47:7:52 | value2 | test.cpp:7:5:7:30 | *ymlStepGenerated_with_body | test.cpp:32:11:32:36 | call to ymlStepGenerated_with_body |
|
||||
| test.cpp:118:44:118:44 | *x | test.cpp:111:3:111:25 | [summary param] *0 in callWithNonTypeTemplate | test.cpp:111:3:111:25 | [summary] to write: ReturnValue in callWithNonTypeTemplate | test.cpp:118:11:118:42 | call to callWithNonTypeTemplate |
|
||||
| test.cpp:134:45:134:45 | x | test.cpp:125:5:125:20 | [summary param] 0 in templateFunction | test.cpp:125:5:125:20 | [summary] to write: ReturnValue in templateFunction | test.cpp:134:13:134:43 | call to templateFunction |
|
||||
| test.cpp:148:26:148:26 | x | test.cpp:140:4:140:11 | [summary param] 1 in function | test.cpp:140:4:140:11 | [summary] to write: ReturnValue in function | test.cpp:148:10:148:27 | call to function |
|
||||
| test.cpp:157:26:157:26 | x | test.cpp:140:4:140:11 | [summary param] 1 in function | test.cpp:140:4:140:11 | [summary] to write: ReturnValue in function | test.cpp:157:13:157:20 | call to function |
|
||||
| test.cpp:165:69:165:69 | x | test.cpp:128:5:128:21 | [summary param] 1 in templateFunction2 | test.cpp:128:5:128:21 | [summary] to write: ReturnValue in templateFunction2 | test.cpp:165:12:165:64 | call to templateFunction2 |
|
||||
| test.cpp:172:51:172:51 | x | test.cpp:164:34:164:34 | x | test.cpp:164:7:164:7 | *templateFunction3 | test.cpp:172:13:172:44 | call to templateFunction3 |
|
||||
| windows.cpp:27:36:27:38 | *cmd | windows.cpp:17:8:17:25 | [summary param] *0 in CommandLineToArgvA | windows.cpp:17:8:17:25 | [summary] to write: ReturnValue[**] in CommandLineToArgvA | windows.cpp:27:17:27:34 | **call to CommandLineToArgvA |
|
||||
| windows.cpp:537:40:537:41 | *& ... | windows.cpp:473:17:473:37 | [summary param] *1 in RtlCopyVolatileMemory | windows.cpp:473:17:473:37 | [summary param] *0 in RtlCopyVolatileMemory [Return] | windows.cpp:537:27:537:37 | RtlCopyVolatileMemory output argument |
|
||||
| windows.cpp:542:38:542:39 | *& ... | windows.cpp:479:17:479:35 | [summary param] *1 in RtlCopyDeviceMemory | windows.cpp:479:17:479:35 | [summary param] *0 in RtlCopyDeviceMemory [Return] | windows.cpp:542:25:542:35 | RtlCopyDeviceMemory output argument |
|
||||
|
||||
@@ -18,4 +18,7 @@ extensions:
|
||||
- ["", "", False, "ymlStepManual_with_body", "", "", "Argument[0]", "ReturnValue", "taint", "manual"]
|
||||
- ["", "", False, "ymlStepGenerated_with_body", "", "", "Argument[0]", "ReturnValue", "taint", "df-generated"]
|
||||
- ["", "", False, "callWithArgument", "", "", "Argument[1]", "Argument[0].Parameter[0]", "value", "manual"]
|
||||
- ["", "", False, "callWithNonTypeTemplate<T>", "(const T &)", "", "Argument[*0]", "ReturnValue", "value", "manual"]
|
||||
- ["", "", False, "callWithNonTypeTemplate<T>", "(const T &)", "", "Argument[*0]", "ReturnValue", "value", "manual"]
|
||||
- ["", "TemplateClass1<T>", False, "templateFunction<U>", "(T,U)", "", "Argument[0]", "ReturnValue", "value", "manual"]
|
||||
- ["", "TemplateClass1", True, "templateFunction2<U,V>", "(U,V)", "", "Argument[1]", "ReturnValue", "value", "manual"]
|
||||
- ["", "TemplateClass2<T,U>", True, "function", "(U,T)", "", "Argument[1]", "ReturnValue", "value", "manual"]
|
||||
@@ -15,3 +15,7 @@
|
||||
| test.cpp:89:11:89:11 | y | test-sink |
|
||||
| test.cpp:116:10:116:11 | y1 | test-sink |
|
||||
| test.cpp:119:10:119:11 | y2 | test-sink |
|
||||
| test.cpp:135:10:135:10 | y | test-sink |
|
||||
| test.cpp:149:10:149:10 | z | test-sink |
|
||||
| test.cpp:158:10:158:10 | z | test-sink |
|
||||
| test.cpp:173:10:173:10 | y | test-sink |
|
||||
|
||||
@@ -9,6 +9,10 @@
|
||||
| test.cpp:56:8:56:16 | call to ymlSource | local |
|
||||
| test.cpp:94:10:94:18 | call to ymlSource | local |
|
||||
| test.cpp:114:10:114:18 | call to ymlSource | local |
|
||||
| test.cpp:133:10:133:18 | call to ymlSource | local |
|
||||
| test.cpp:146:10:146:18 | call to ymlSource | local |
|
||||
| test.cpp:155:10:155:18 | call to ymlSource | local |
|
||||
| test.cpp:170:10:170:18 | call to ymlSource | local |
|
||||
| windows.cpp:22:15:22:29 | *call to GetCommandLineA | local |
|
||||
| windows.cpp:34:17:34:38 | *call to GetEnvironmentStringsA | local |
|
||||
| windows.cpp:39:36:39:38 | GetEnvironmentVariableA output argument | local |
|
||||
|
||||
@@ -118,3 +118,57 @@ void test_callWithNonTypeTemplate() {
|
||||
int y2 = callWithNonTypeTemplate<int, 10>(x);
|
||||
ymlSink(y2); // $ ir
|
||||
}
|
||||
|
||||
template<class T>
|
||||
struct TemplateClass1 {
|
||||
template<class U>
|
||||
U templateFunction(T, U);
|
||||
|
||||
template<class U, class V>
|
||||
V templateFunction2(U, V);
|
||||
};
|
||||
|
||||
void test_template_function_in_template_class() {
|
||||
TemplateClass1<int> b;
|
||||
int x = ymlSource();
|
||||
auto y = b.templateFunction<unsigned long>(x, 0UL);
|
||||
ymlSink(y); // $ ir
|
||||
}
|
||||
|
||||
template<class S, class T>
|
||||
struct TemplateClass2 {
|
||||
T function(T, S);
|
||||
};
|
||||
|
||||
template<class V> using PartialInstantiationOfTemplateClass2 = TemplateClass2<int, V>;
|
||||
|
||||
void test_partial_class_instantiation() {
|
||||
int x = ymlSource();
|
||||
PartialInstantiationOfTemplateClass2<unsigned long> y;
|
||||
int z = y.function(0UL, x);
|
||||
ymlSink(z); // $ ir
|
||||
}
|
||||
|
||||
template<class V> struct DeriveFromFromPartialTemplateInstantiation : TemplateClass2<int, V> { };
|
||||
|
||||
void test_inheritance() {
|
||||
int x = ymlSource();
|
||||
DeriveFromFromPartialTemplateInstantiation<long> y;
|
||||
auto z = y.function(0L, x);
|
||||
ymlSink(z); // $ ir
|
||||
}
|
||||
|
||||
template<class T>
|
||||
struct Class1 : TemplateClass1<T> {
|
||||
template<class U>
|
||||
int templateFunction3(U u, int x) {
|
||||
return TemplateClass1<T>::template templateFunction2<U, int>(u, x);
|
||||
}
|
||||
};
|
||||
|
||||
void test_class1() {
|
||||
int x = ymlSource();
|
||||
Class1<int> c;
|
||||
auto y = c.templateFunction3<unsigned long>(0UL, x);
|
||||
ymlSink(y); // $ ir
|
||||
}
|
||||
@@ -27383,54 +27383,55 @@ getParameterTypeName
|
||||
| stl.h:91:24:91:33 | operator++ | 0 | int |
|
||||
| stl.h:95:44:95:44 | back_inserter | 0 | func:0 & |
|
||||
| stl.h:95:44:95:44 | back_inserter | 0 | func:0 & |
|
||||
| stl.h:148:3:148:14 | basic_string | 0 | const class:2 & |
|
||||
| stl.h:149:33:149:44 | basic_string | 0 | const class:0 * |
|
||||
| stl.h:149:33:149:44 | basic_string | 1 | const class:2 & |
|
||||
| stl.h:151:16:151:20 | c_str | 0 | func:0 |
|
||||
| stl.h:151:16:151:20 | c_str | 1 | func:0 |
|
||||
| stl.h:151:16:151:20 | c_str | 2 | const class:2 & |
|
||||
| stl.h:147:12:147:23 | basic_string | 0 | const class:2 & |
|
||||
| stl.h:148:3:148:14 | basic_string | 0 | const class:0 * |
|
||||
| stl.h:148:3:148:14 | basic_string | 1 | const class:2 & |
|
||||
| stl.h:149:33:149:44 | basic_string | 0 | func:0 |
|
||||
| stl.h:149:33:149:44 | basic_string | 1 | func:0 |
|
||||
| stl.h:149:33:149:44 | basic_string | 2 | const class:2 & |
|
||||
| stl.h:165:8:165:16 | push_back | 0 | class:0 |
|
||||
| stl.h:173:13:173:22 | operator[] | 0 | size_type |
|
||||
| stl.h:175:13:175:14 | at | 0 | size_type |
|
||||
| stl.h:176:35:176:44 | operator+= | 0 | size_type |
|
||||
| stl.h:176:35:176:44 | operator+= | 0 | size_type |
|
||||
| stl.h:177:17:177:26 | operator+= | 0 | const func:0 & |
|
||||
| stl.h:178:17:178:22 | append | 0 | const class:0 * |
|
||||
| stl.h:179:17:179:22 | append | 0 | const basic_string & |
|
||||
| stl.h:180:17:180:22 | append | 0 | const class:0 * |
|
||||
| stl.h:181:47:181:52 | append | 0 | size_type |
|
||||
| stl.h:181:47:181:52 | append | 1 | class:0 |
|
||||
| stl.h:182:17:182:22 | assign | 0 | func:0 |
|
||||
| stl.h:182:17:182:22 | assign | 1 | func:0 |
|
||||
| stl.h:183:17:183:22 | assign | 0 | const basic_string & |
|
||||
| stl.h:184:47:184:52 | assign | 0 | size_type |
|
||||
| stl.h:184:47:184:52 | assign | 1 | class:0 |
|
||||
| stl.h:185:17:185:22 | insert | 0 | func:0 |
|
||||
| stl.h:185:17:185:22 | insert | 1 | func:0 |
|
||||
| stl.h:176:35:176:44 | operator+= | 0 | const func:0 & |
|
||||
| stl.h:176:35:176:44 | operator+= | 0 | const func:0 & |
|
||||
| stl.h:177:17:177:26 | operator+= | 0 | const class:0 * |
|
||||
| stl.h:178:17:178:22 | append | 0 | const basic_string & |
|
||||
| stl.h:179:17:179:22 | append | 0 | const class:0 * |
|
||||
| stl.h:180:17:180:22 | append | 0 | size_type |
|
||||
| stl.h:180:17:180:22 | append | 1 | class:0 |
|
||||
| stl.h:181:47:181:52 | append | 0 | func:0 |
|
||||
| stl.h:181:47:181:52 | append | 1 | func:0 |
|
||||
| stl.h:182:17:182:22 | assign | 0 | const basic_string & |
|
||||
| stl.h:183:17:183:22 | assign | 0 | size_type |
|
||||
| stl.h:183:17:183:22 | assign | 1 | class:0 |
|
||||
| stl.h:184:47:184:52 | assign | 0 | func:0 |
|
||||
| stl.h:184:47:184:52 | assign | 1 | func:0 |
|
||||
| stl.h:185:17:185:22 | insert | 0 | size_type |
|
||||
| stl.h:185:17:185:22 | insert | 1 | const basic_string & |
|
||||
| stl.h:186:17:186:22 | insert | 0 | size_type |
|
||||
| stl.h:186:17:186:22 | insert | 1 | const basic_string & |
|
||||
| stl.h:186:17:186:22 | insert | 1 | size_type |
|
||||
| stl.h:186:17:186:22 | insert | 2 | class:0 |
|
||||
| stl.h:187:17:187:22 | insert | 0 | size_type |
|
||||
| stl.h:187:17:187:22 | insert | 1 | size_type |
|
||||
| stl.h:187:17:187:22 | insert | 2 | class:0 |
|
||||
| stl.h:188:12:188:17 | insert | 0 | size_type |
|
||||
| stl.h:188:12:188:17 | insert | 1 | const class:0 * |
|
||||
| stl.h:187:17:187:22 | insert | 1 | const class:0 * |
|
||||
| stl.h:188:12:188:17 | insert | 0 | const_iterator |
|
||||
| stl.h:188:12:188:17 | insert | 1 | size_type |
|
||||
| stl.h:188:12:188:17 | insert | 2 | class:0 |
|
||||
| stl.h:189:42:189:47 | insert | 0 | const_iterator |
|
||||
| stl.h:189:42:189:47 | insert | 1 | size_type |
|
||||
| stl.h:189:42:189:47 | insert | 2 | class:0 |
|
||||
| stl.h:190:17:190:23 | replace | 0 | const_iterator |
|
||||
| stl.h:190:17:190:23 | replace | 1 | func:0 |
|
||||
| stl.h:190:17:190:23 | replace | 2 | func:0 |
|
||||
| stl.h:189:42:189:47 | insert | 1 | func:0 |
|
||||
| stl.h:189:42:189:47 | insert | 2 | func:0 |
|
||||
| stl.h:190:17:190:23 | replace | 0 | size_type |
|
||||
| stl.h:190:17:190:23 | replace | 1 | size_type |
|
||||
| stl.h:190:17:190:23 | replace | 2 | const basic_string & |
|
||||
| stl.h:191:17:191:23 | replace | 0 | size_type |
|
||||
| stl.h:191:17:191:23 | replace | 1 | size_type |
|
||||
| stl.h:191:17:191:23 | replace | 2 | const basic_string & |
|
||||
| stl.h:192:13:192:16 | copy | 0 | size_type |
|
||||
| stl.h:191:17:191:23 | replace | 2 | size_type |
|
||||
| stl.h:191:17:191:23 | replace | 3 | class:0 |
|
||||
| stl.h:192:13:192:16 | copy | 0 | class:0 * |
|
||||
| stl.h:192:13:192:16 | copy | 1 | size_type |
|
||||
| stl.h:192:13:192:16 | copy | 2 | size_type |
|
||||
| stl.h:192:13:192:16 | copy | 3 | class:0 |
|
||||
| stl.h:193:8:193:12 | clear | 0 | class:0 * |
|
||||
| stl.h:193:8:193:12 | clear | 1 | size_type |
|
||||
| stl.h:193:8:193:12 | clear | 2 | size_type |
|
||||
| stl.h:195:8:195:11 | swap | 0 | size_type |
|
||||
| stl.h:195:8:195:11 | swap | 1 | size_type |
|
||||
| stl.h:194:16:194:21 | substr | 0 | size_type |
|
||||
| stl.h:194:16:194:21 | substr | 1 | size_type |
|
||||
| stl.h:195:8:195:11 | swap | 0 | basic_string & |
|
||||
| stl.h:198:94:198:102 | operator+ | 0 | const basic_string & |
|
||||
| stl.h:198:94:198:102 | operator+ | 1 | const basic_string & |
|
||||
| stl.h:199:94:199:102 | operator+ | 0 | const basic_string & |
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
| inconsistency2.cpp:3:3:3:5 | T:: | inconsistency2.cpp:3:3:3:6 | x | inconsistency2.cpp:2:20:2:20 | T |
|
||||
| inconsistency2.cpp:3:3:3:11 | const s:: | inconsistency2.cpp:3:3:3:6 | x | file://:0:0:0:0 | const s |
|
||||
| inconsistency.cpp:7:20:7:22 | S:: | inconsistency.cpp:7:20:7:23 | (int)... | inconsistency.cpp:4:8:4:8 | S |
|
||||
| inconsistency.cpp:7:20:7:22 | S:: | inconsistency.cpp:7:20:7:23 | A | inconsistency.cpp:4:8:4:8 | S |
|
||||
| name_qualifiers.cpp:29:7:29:8 | :: | name_qualifiers.cpp:29:7:29:9 | x | file://:0:0:0:0 | (global namespace) |
|
||||
| name_qualifiers.cpp:31:7:31:10 | N1:: | name_qualifiers.cpp:31:7:31:12 | nx | name_qualifiers.cpp:4:11:4:12 | N1 |
|
||||
| name_qualifiers.cpp:34:7:34:8 | :: | name_qualifiers.cpp:34:9:34:12 | N1:: | file://:0:0:0:0 | (global namespace) |
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
import cpp
|
||||
|
||||
from NameQualifier nq, Location l
|
||||
where
|
||||
l = nq.getQualifiedElement().getLocation() and
|
||||
l.getFile().getShortName() = "name_qualifiers"
|
||||
where l = nq.getQualifiedElement().getLocation()
|
||||
select nq, nq.getQualifiedElement(), nq.getQualifyingElement()
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
// This file is present to test whether name-qualifying an enum constant leads to a database inconsistency.
|
||||
// As such, there is no QL part of the test.
|
||||
|
||||
|
||||
struct S { enum E { A }; };
|
||||
|
||||
static int f() {
|
||||
static void f() {
|
||||
switch(0) { case S::A: break; }
|
||||
}
|
||||
|
||||
12
cpp/ql/test/library-tests/name_qualifiers/inconsistency2.cpp
Normal file
12
cpp/ql/test/library-tests/name_qualifiers/inconsistency2.cpp
Normal file
@@ -0,0 +1,12 @@
|
||||
namespace {
|
||||
template <typename T> T f() {
|
||||
T::x;
|
||||
return {};
|
||||
}
|
||||
struct s {
|
||||
static int x;
|
||||
};
|
||||
struct t {
|
||||
s x = f<const s>();
|
||||
};
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,2 @@
|
||||
description: Restructure and rename types related to operations.
|
||||
compatibility: full
|
||||
@@ -1,304 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using Semmle.Util;
|
||||
|
||||
namespace Semmle.Extraction.CSharp.DependencyFetching
|
||||
{
|
||||
/// <summary>
|
||||
/// Manage the downloading of NuGet packages with nuget.exe.
|
||||
/// Locates packages in a source tree and downloads all of the
|
||||
/// referenced assemblies to a temp folder.
|
||||
/// </summary>
|
||||
internal class NugetExeWrapper : IDisposable
|
||||
{
|
||||
private readonly string? nugetExe;
|
||||
private readonly Semmle.Util.Logging.ILogger logger;
|
||||
|
||||
public int PackageCount => fileProvider.PackagesConfigs.Count;
|
||||
|
||||
private readonly string? backupNugetConfig;
|
||||
private readonly string? nugetConfigPath;
|
||||
private readonly FileProvider fileProvider;
|
||||
|
||||
/// <summary>
|
||||
/// The packages directory.
|
||||
/// This will be in the user-specified or computed Temp location
|
||||
/// so as to not trample the source tree.
|
||||
/// </summary>
|
||||
private readonly DependencyDirectory packageDirectory;
|
||||
|
||||
/// <summary>
|
||||
/// Create the package manager for a specified source tree.
|
||||
/// </summary>
|
||||
public NugetExeWrapper(FileProvider fileProvider, DependencyDirectory packageDirectory, Semmle.Util.Logging.ILogger logger, Func<bool> useDefaultFeed)
|
||||
{
|
||||
this.fileProvider = fileProvider;
|
||||
this.packageDirectory = packageDirectory;
|
||||
this.logger = logger;
|
||||
|
||||
if (fileProvider.PackagesConfigs.Count > 0)
|
||||
{
|
||||
logger.LogInfo($"Found packages.config files, trying to use nuget.exe for package restore");
|
||||
nugetExe = ResolveNugetExe();
|
||||
if (HasNoPackageSource() && useDefaultFeed())
|
||||
{
|
||||
// We only modify or add a top level nuget.config file
|
||||
nugetConfigPath = Path.Combine(fileProvider.SourceDir.FullName, "nuget.config");
|
||||
try
|
||||
{
|
||||
if (File.Exists(nugetConfigPath))
|
||||
{
|
||||
var tempFolderPath = FileUtils.GetTemporaryWorkingDirectory(out _);
|
||||
|
||||
do
|
||||
{
|
||||
backupNugetConfig = Path.Combine(tempFolderPath, Path.GetRandomFileName());
|
||||
}
|
||||
while (File.Exists(backupNugetConfig));
|
||||
File.Copy(nugetConfigPath, backupNugetConfig, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
File.WriteAllText(nugetConfigPath,
|
||||
"""
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<configuration>
|
||||
<packageSources>
|
||||
</packageSources>
|
||||
</configuration>
|
||||
""");
|
||||
}
|
||||
AddDefaultPackageSource(nugetConfigPath);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
logger.LogError($"Failed to add default package source to {nugetConfigPath}: {e}");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tries to find the location of `nuget.exe`. It looks for
|
||||
/// - the environment variable specifying a location,
|
||||
/// - files in the repository,
|
||||
/// - tries to resolve nuget from the PATH, or
|
||||
/// - downloads it if it is not found.
|
||||
/// </summary>
|
||||
private string ResolveNugetExe()
|
||||
{
|
||||
var envVarPath = Environment.GetEnvironmentVariable(EnvironmentVariableNames.NugetExePath);
|
||||
if (!string.IsNullOrEmpty(envVarPath))
|
||||
{
|
||||
logger.LogInfo($"Using nuget.exe from environment variable: '{envVarPath}'");
|
||||
return envVarPath;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
return DownloadNugetExe(fileProvider.SourceDir.FullName);
|
||||
}
|
||||
catch (Exception exc)
|
||||
{
|
||||
logger.LogInfo($"Download of nuget.exe failed: {exc.Message}");
|
||||
}
|
||||
|
||||
var nugetExesInRepo = fileProvider.NugetExes;
|
||||
if (nugetExesInRepo.Count > 1)
|
||||
{
|
||||
logger.LogInfo($"Found multiple nuget.exe files in the repository: {string.Join(", ", nugetExesInRepo.OrderBy(s => s))}");
|
||||
}
|
||||
|
||||
if (nugetExesInRepo.Count > 0)
|
||||
{
|
||||
var path = nugetExesInRepo.First();
|
||||
logger.LogInfo($"Using nuget.exe from path '{path}'");
|
||||
return path;
|
||||
}
|
||||
|
||||
var executableName = Win32.IsWindows() ? "nuget.exe" : "nuget";
|
||||
var nugetPath = FileUtils.FindProgramOnPath(executableName);
|
||||
if (nugetPath is not null)
|
||||
{
|
||||
nugetPath = Path.Combine(nugetPath, executableName);
|
||||
logger.LogInfo($"Using nuget.exe from PATH: {nugetPath}");
|
||||
return nugetPath;
|
||||
}
|
||||
|
||||
throw new Exception("Could not find or download nuget.exe.");
|
||||
}
|
||||
|
||||
private string DownloadNugetExe(string sourceDir)
|
||||
{
|
||||
var directory = Path.Combine(sourceDir, ".nuget");
|
||||
var nuget = Path.Combine(directory, "nuget.exe");
|
||||
|
||||
// Nuget.exe already exists in the .nuget directory.
|
||||
if (File.Exists(nuget))
|
||||
{
|
||||
logger.LogInfo($"Found nuget.exe at {nuget}");
|
||||
return nuget;
|
||||
}
|
||||
|
||||
Directory.CreateDirectory(directory);
|
||||
logger.LogInfo("Attempting to download nuget.exe");
|
||||
FileUtils.DownloadFile(FileUtils.NugetExeUrl, nuget, logger);
|
||||
logger.LogInfo($"Downloaded nuget.exe to {nuget}");
|
||||
return nuget;
|
||||
}
|
||||
|
||||
private bool RunWithMono => !Win32.IsWindows() && !string.IsNullOrEmpty(Path.GetExtension(nugetExe));
|
||||
|
||||
/// <summary>
|
||||
/// Restore all packages in the specified packages.config file.
|
||||
/// </summary>
|
||||
/// <param name="packagesConfig">The packages.config file.</param>
|
||||
private bool TryRestoreNugetPackage(string packagesConfig)
|
||||
{
|
||||
logger.LogInfo($"Restoring file \"{packagesConfig}\"...");
|
||||
|
||||
/* Use nuget.exe to install a package.
|
||||
* Note that there is a clutch of NuGet assemblies which could be used to
|
||||
* invoke this directly, which would arguably be nicer. However they are
|
||||
* really unwieldy and this solution works for now.
|
||||
*/
|
||||
|
||||
string exe, args;
|
||||
if (RunWithMono)
|
||||
{
|
||||
exe = "mono";
|
||||
args = $"\"{nugetExe}\" install -OutputDirectory \"{packageDirectory}\" \"{packagesConfig}\"";
|
||||
}
|
||||
else
|
||||
{
|
||||
exe = nugetExe!;
|
||||
args = $"install -OutputDirectory \"{packageDirectory}\" \"{packagesConfig}\"";
|
||||
}
|
||||
|
||||
var pi = new ProcessStartInfo(exe, args)
|
||||
{
|
||||
RedirectStandardOutput = true,
|
||||
RedirectStandardError = true,
|
||||
UseShellExecute = false
|
||||
};
|
||||
|
||||
var threadId = Environment.CurrentManagedThreadId;
|
||||
void onOut(string s) => logger.LogDebug(s, threadId);
|
||||
void onError(string s) => logger.LogError(s, threadId);
|
||||
var exitCode = pi.ReadOutput(out _, onOut, onError);
|
||||
if (exitCode != 0)
|
||||
{
|
||||
logger.LogError($"Command {pi.FileName} {pi.Arguments} failed with exit code {exitCode}");
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
logger.LogInfo($"Restored file \"{packagesConfig}\"");
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Download the packages to the temp folder.
|
||||
/// </summary>
|
||||
public int InstallPackages()
|
||||
{
|
||||
return fileProvider.PackagesConfigs.Count(TryRestoreNugetPackage);
|
||||
}
|
||||
|
||||
private bool HasNoPackageSource()
|
||||
{
|
||||
if (Win32.IsWindows())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
logger.LogInfo("Checking if default package source is available...");
|
||||
RunMonoNugetCommand("sources list -ForceEnglishOutput", out var stdout);
|
||||
if (stdout.All(line => line != "No sources found."))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
logger.LogWarning($"Failed to check if default package source is added: {e}");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private void RunMonoNugetCommand(string command, out IList<string> stdout)
|
||||
{
|
||||
string exe, args;
|
||||
if (RunWithMono)
|
||||
{
|
||||
exe = "mono";
|
||||
args = $"\"{nugetExe}\" {command}";
|
||||
}
|
||||
else
|
||||
{
|
||||
exe = nugetExe!;
|
||||
args = command;
|
||||
}
|
||||
|
||||
var pi = new ProcessStartInfo(exe, args)
|
||||
{
|
||||
RedirectStandardOutput = true,
|
||||
RedirectStandardError = true,
|
||||
UseShellExecute = false
|
||||
};
|
||||
|
||||
var threadId = Environment.CurrentManagedThreadId;
|
||||
void onOut(string s) => logger.LogDebug(s, threadId);
|
||||
void onError(string s) => logger.LogError(s, threadId);
|
||||
pi.ReadOutput(out stdout, onOut, onError);
|
||||
}
|
||||
|
||||
private void AddDefaultPackageSource(string nugetConfig)
|
||||
{
|
||||
logger.LogInfo("Adding default package source...");
|
||||
RunMonoNugetCommand($"sources add -Name DefaultNugetOrg -Source {NugetPackageRestorer.PublicNugetOrgFeed} -ConfigFile \"{nugetConfig}\"", out _);
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
if (nugetConfigPath is null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
if (backupNugetConfig is null)
|
||||
{
|
||||
logger.LogInfo("Removing nuget.config file");
|
||||
File.Delete(nugetConfigPath);
|
||||
return;
|
||||
}
|
||||
|
||||
logger.LogInfo("Reverting nuget.config file content");
|
||||
// The content of the original nuget.config file is reverted without changing the file's attributes or casing:
|
||||
using (var backup = File.OpenRead(backupNugetConfig))
|
||||
using (var current = File.OpenWrite(nugetConfigPath))
|
||||
{
|
||||
current.SetLength(0); // Truncate file
|
||||
backup.CopyTo(current); // Restore original content
|
||||
}
|
||||
|
||||
logger.LogInfo("Deleting backup nuget.config file");
|
||||
File.Delete(backupNugetConfig);
|
||||
}
|
||||
catch (Exception exc)
|
||||
{
|
||||
logger.LogError($"Failed to restore original nuget.config file: {exc}");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -161,13 +161,13 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
|
||||
reachableFeeds.UnionWith(reachableInheritedFeeds);
|
||||
}
|
||||
|
||||
using (var nuget = new NugetExeWrapper(fileProvider, legacyPackageDirectory, logger, IsDefaultFeedReachable))
|
||||
using (var packagesConfigRestore = PackagesConfigRestoreFactory.Create(fileProvider, legacyPackageDirectory, logger, IsDefaultFeedReachable))
|
||||
{
|
||||
var count = nuget.InstallPackages();
|
||||
var count = packagesConfigRestore.InstallPackages();
|
||||
|
||||
if (nuget.PackageCount > 0)
|
||||
if (packagesConfigRestore.PackageCount > 0)
|
||||
{
|
||||
compilationInfoContainer.CompilationInfos.Add(("packages.config files", nuget.PackageCount.ToString()));
|
||||
compilationInfoContainer.CompilationInfos.Add(("packages.config files", packagesConfigRestore.PackageCount.ToString()));
|
||||
compilationInfoContainer.CompilationInfos.Add(("Successfully restored packages.config files", count.ToString()));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,368 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using Semmle.Util;
|
||||
|
||||
namespace Semmle.Extraction.CSharp.DependencyFetching
|
||||
{
|
||||
internal interface IPackagesConfigRestore : IDisposable
|
||||
{
|
||||
/// <summary>
|
||||
/// The number of packages.config files found in the source tree.
|
||||
/// </summary>
|
||||
int PackageCount { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Download the packages to the temp folder.
|
||||
/// </summary>
|
||||
int InstallPackages();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Factory for creating a package manager to restore NuGet packages referenced in packages.config files.
|
||||
/// If the environment doesn't support using nuget.exe to restore packages from packages.config files, a no-op implementation is returned.
|
||||
/// It is worth noting that for macOS and Linux, nuget.exe is used with mono. However, mono is being deprecated and the last GitHub images
|
||||
/// to contain mono are:
|
||||
/// - Ubuntu 22.04
|
||||
/// - macOS 14
|
||||
///
|
||||
/// If the packages from the packages.config files are not restored with the packages.config restore functionality below, there is a subsequent
|
||||
/// step that still may succeed in restoring the packages without the help of nuget.exe (by attempting to restore using dotnet).
|
||||
/// </summary>
|
||||
internal class PackagesConfigRestoreFactory
|
||||
{
|
||||
public static IPackagesConfigRestore Create(FileProvider fileProvider, DependencyDirectory packageDirectory, Semmle.Util.Logging.ILogger logger, Func<bool> useDefaultFeed)
|
||||
{
|
||||
if (SystemBuildActions.Instance.IsWindows() || SystemBuildActions.Instance.IsMonoInstalled())
|
||||
{
|
||||
return new NugetExeWrapper(fileProvider, packageDirectory, logger, useDefaultFeed);
|
||||
}
|
||||
|
||||
return new NoOpPackagesConfig(fileProvider, logger);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Manage the downloading of NuGet packages with nuget.exe.
|
||||
/// Locates packages in a source tree and downloads all of the
|
||||
/// referenced assemblies to a temp folder.
|
||||
/// </summary>
|
||||
private class NugetExeWrapper : IPackagesConfigRestore
|
||||
{
|
||||
private readonly string? nugetExe;
|
||||
private readonly Semmle.Util.Logging.ILogger logger;
|
||||
|
||||
public int PackageCount => fileProvider.PackagesConfigs.Count;
|
||||
|
||||
private readonly string? backupNugetConfig;
|
||||
private readonly string? nugetConfigPath;
|
||||
private readonly FileProvider fileProvider;
|
||||
|
||||
/// <summary>
|
||||
/// The packages directory.
|
||||
/// This will be in the user-specified or computed Temp location
|
||||
/// so as to not trample the source tree.
|
||||
/// </summary>
|
||||
private readonly DependencyDirectory packageDirectory;
|
||||
|
||||
private bool IsWindows => SystemBuildActions.Instance.IsWindows();
|
||||
|
||||
/// <summary>
|
||||
/// Create the package manager for a specified source tree.
|
||||
/// </summary>
|
||||
public NugetExeWrapper(FileProvider fileProvider, DependencyDirectory packageDirectory, Semmle.Util.Logging.ILogger logger, Func<bool> useDefaultFeed)
|
||||
{
|
||||
this.fileProvider = fileProvider;
|
||||
this.packageDirectory = packageDirectory;
|
||||
this.logger = logger;
|
||||
|
||||
if (fileProvider.PackagesConfigs.Count > 0)
|
||||
{
|
||||
logger.LogInfo($"Found packages.config files, trying to use nuget.exe for package restore");
|
||||
nugetExe = ResolveNugetExe();
|
||||
if (!HasPackageSource() && useDefaultFeed())
|
||||
{
|
||||
// We only modify or add a top level nuget.config file
|
||||
nugetConfigPath = Path.Join(fileProvider.SourceDir.FullName, "nuget.config");
|
||||
try
|
||||
{
|
||||
if (File.Exists(nugetConfigPath))
|
||||
{
|
||||
var tempFolderPath = FileUtils.GetTemporaryWorkingDirectory(out _);
|
||||
|
||||
do
|
||||
{
|
||||
backupNugetConfig = Path.Join(tempFolderPath, Path.GetRandomFileName());
|
||||
}
|
||||
while (File.Exists(backupNugetConfig));
|
||||
File.Copy(nugetConfigPath, backupNugetConfig, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
File.WriteAllText(nugetConfigPath,
|
||||
"""
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<configuration>
|
||||
<packageSources>
|
||||
</packageSources>
|
||||
</configuration>
|
||||
""");
|
||||
}
|
||||
AddDefaultPackageSource(nugetConfigPath);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
logger.LogError($"Failed to add default package source to {nugetConfigPath}: {e}");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tries to find the location of `nuget.exe`. It looks for
|
||||
/// - the environment variable specifying a location,
|
||||
/// - files in the repository,
|
||||
/// - tries to resolve nuget from the PATH, or
|
||||
/// - downloads it if it is not found.
|
||||
/// </summary>
|
||||
private string ResolveNugetExe()
|
||||
{
|
||||
var envVarPath = Environment.GetEnvironmentVariable(EnvironmentVariableNames.NugetExePath);
|
||||
if (!string.IsNullOrEmpty(envVarPath))
|
||||
{
|
||||
logger.LogInfo($"Using nuget.exe from environment variable: '{envVarPath}'");
|
||||
return envVarPath;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
return DownloadNugetExe(fileProvider.SourceDir.FullName);
|
||||
}
|
||||
catch (Exception exc)
|
||||
{
|
||||
logger.LogInfo($"Download of nuget.exe failed: {exc.Message}");
|
||||
}
|
||||
|
||||
var nugetExesInRepo = fileProvider.NugetExes;
|
||||
if (nugetExesInRepo.Count > 1)
|
||||
{
|
||||
logger.LogInfo($"Found multiple nuget.exe files in the repository: {string.Join(", ", nugetExesInRepo.OrderBy(s => s))}");
|
||||
}
|
||||
|
||||
if (nugetExesInRepo.Count > 0)
|
||||
{
|
||||
var path = nugetExesInRepo.First();
|
||||
logger.LogInfo($"Using nuget.exe from path '{path}'");
|
||||
return path;
|
||||
}
|
||||
|
||||
var executableName = IsWindows ? "nuget.exe" : "nuget";
|
||||
var nugetPath = FileUtils.FindProgramOnPath(executableName);
|
||||
if (nugetPath is not null)
|
||||
{
|
||||
nugetPath = Path.Join(nugetPath, executableName);
|
||||
logger.LogInfo($"Using nuget.exe from PATH: {nugetPath}");
|
||||
return nugetPath;
|
||||
}
|
||||
|
||||
throw new Exception("Could not find or download nuget.exe.");
|
||||
}
|
||||
|
||||
private string DownloadNugetExe(string sourceDir)
|
||||
{
|
||||
var directory = Path.Join(sourceDir, ".nuget");
|
||||
var nuget = Path.Join(directory, "nuget.exe");
|
||||
|
||||
// Nuget.exe already exists in the .nuget directory.
|
||||
if (File.Exists(nuget))
|
||||
{
|
||||
logger.LogInfo($"Found nuget.exe at {nuget}");
|
||||
return nuget;
|
||||
}
|
||||
|
||||
Directory.CreateDirectory(directory);
|
||||
logger.LogInfo("Attempting to download nuget.exe");
|
||||
FileUtils.DownloadFile(FileUtils.NugetExeUrl, nuget, logger);
|
||||
logger.LogInfo($"Downloaded nuget.exe to {nuget}");
|
||||
return nuget;
|
||||
}
|
||||
|
||||
private bool RunWithMono => !IsWindows && !string.IsNullOrEmpty(Path.GetExtension(nugetExe));
|
||||
|
||||
/// <summary>
|
||||
/// Restore all packages in the specified packages.config file.
|
||||
/// </summary>
|
||||
/// <param name="packagesConfig">The packages.config file.</param>
|
||||
private bool TryRestoreNugetPackage(string packagesConfig)
|
||||
{
|
||||
logger.LogInfo($"Restoring file \"{packagesConfig}\"...");
|
||||
|
||||
/* Use nuget.exe to install a package.
|
||||
* Note that there is a clutch of NuGet assemblies which could be used to
|
||||
* invoke this directly, which would arguably be nicer. However they are
|
||||
* really unwieldy and this solution works for now.
|
||||
*/
|
||||
|
||||
string exe, args;
|
||||
if (RunWithMono)
|
||||
{
|
||||
exe = "mono";
|
||||
args = $"\"{nugetExe}\" install -OutputDirectory \"{packageDirectory}\" \"{packagesConfig}\"";
|
||||
}
|
||||
else
|
||||
{
|
||||
exe = nugetExe!;
|
||||
args = $"install -OutputDirectory \"{packageDirectory}\" \"{packagesConfig}\"";
|
||||
}
|
||||
|
||||
var pi = new ProcessStartInfo(exe, args)
|
||||
{
|
||||
RedirectStandardOutput = true,
|
||||
RedirectStandardError = true,
|
||||
UseShellExecute = false
|
||||
};
|
||||
|
||||
var threadId = Environment.CurrentManagedThreadId;
|
||||
void onOut(string s) => logger.LogDebug(s, threadId);
|
||||
void onError(string s) => logger.LogError(s, threadId);
|
||||
var exitCode = pi.ReadOutput(out _, onOut, onError);
|
||||
if (exitCode != 0)
|
||||
{
|
||||
logger.LogError($"Command {pi.FileName} {pi.Arguments} failed with exit code {exitCode}");
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
logger.LogInfo($"Restored file \"{packagesConfig}\"");
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Download the packages to the temp folder.
|
||||
/// </summary>
|
||||
public int InstallPackages()
|
||||
{
|
||||
return fileProvider.PackagesConfigs.Count(TryRestoreNugetPackage);
|
||||
}
|
||||
|
||||
private bool HasPackageSource()
|
||||
{
|
||||
if (IsWindows)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
logger.LogInfo("Checking if default package source is available...");
|
||||
RunMonoNugetCommand("sources list -ForceEnglishOutput", out var stdout);
|
||||
if (stdout.All(line => line != "No sources found."))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
logger.LogWarning($"Failed to check if default package source is added: {e}");
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
private void RunMonoNugetCommand(string command, out IList<string> stdout)
|
||||
{
|
||||
string exe, args;
|
||||
if (RunWithMono)
|
||||
{
|
||||
exe = "mono";
|
||||
args = $"\"{nugetExe}\" {command}";
|
||||
}
|
||||
else
|
||||
{
|
||||
exe = nugetExe!;
|
||||
args = command;
|
||||
}
|
||||
|
||||
var pi = new ProcessStartInfo(exe, args)
|
||||
{
|
||||
RedirectStandardOutput = true,
|
||||
RedirectStandardError = true,
|
||||
UseShellExecute = false
|
||||
};
|
||||
|
||||
var threadId = Environment.CurrentManagedThreadId;
|
||||
void onOut(string s) => logger.LogDebug(s, threadId);
|
||||
void onError(string s) => logger.LogError(s, threadId);
|
||||
pi.ReadOutput(out stdout, onOut, onError);
|
||||
}
|
||||
|
||||
private void AddDefaultPackageSource(string nugetConfig)
|
||||
{
|
||||
logger.LogInfo("Adding default package source...");
|
||||
RunMonoNugetCommand($"sources add -Name DefaultNugetOrg -Source {NugetPackageRestorer.PublicNugetOrgFeed} -ConfigFile \"{nugetConfig}\"", out _);
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
if (nugetConfigPath is null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
if (backupNugetConfig is null)
|
||||
{
|
||||
logger.LogInfo("Removing nuget.config file");
|
||||
File.Delete(nugetConfigPath);
|
||||
return;
|
||||
}
|
||||
|
||||
logger.LogInfo("Reverting nuget.config file content");
|
||||
// The content of the original nuget.config file is reverted without changing the file's attributes or casing:
|
||||
using (var backup = File.OpenRead(backupNugetConfig))
|
||||
using (var current = File.OpenWrite(nugetConfigPath))
|
||||
{
|
||||
current.SetLength(0); // Truncate file
|
||||
backup.CopyTo(current); // Restore original content
|
||||
}
|
||||
|
||||
logger.LogInfo("Deleting backup nuget.config file");
|
||||
File.Delete(backupNugetConfig);
|
||||
}
|
||||
catch (Exception exc)
|
||||
{
|
||||
logger.LogError($"Failed to restore original nuget.config file: {exc}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private class NoOpPackagesConfig : IPackagesConfigRestore
|
||||
{
|
||||
private readonly Semmle.Util.Logging.ILogger logger;
|
||||
private readonly FileProvider fileProvider;
|
||||
|
||||
public NoOpPackagesConfig(FileProvider fileProvider, Semmle.Util.Logging.ILogger logger)
|
||||
{
|
||||
this.fileProvider = fileProvider;
|
||||
this.logger = logger;
|
||||
}
|
||||
|
||||
public int PackageCount => fileProvider.PackagesConfigs.Count;
|
||||
|
||||
public int InstallPackages()
|
||||
{
|
||||
if (PackageCount > 0)
|
||||
{
|
||||
logger.LogInfo("Found packages.config files, but nuget.exe cannot be used to restore packages on this platform. Skipping restore of packages.config files.");
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
public void Dispose() { }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
using System.IO;
|
||||
using Microsoft.CodeAnalysis;
|
||||
using Microsoft.CodeAnalysis.CSharp;
|
||||
using Microsoft.CodeAnalysis.CSharp.Syntax;
|
||||
using Semmle.Extraction.Kinds;
|
||||
|
||||
@@ -8,7 +9,7 @@ namespace Semmle.Extraction.CSharp.Entities.Expressions
|
||||
internal abstract class ElementAccess : Expression<ExpressionSyntax>
|
||||
{
|
||||
protected ElementAccess(ExpressionNodeInfo info, ExpressionSyntax qualifier, BracketedArgumentListSyntax argumentList)
|
||||
: base(info.SetKind(GetKind(info.Context, qualifier)))
|
||||
: base(info.SetKind(GetKind(info.Context, info.Node, qualifier)))
|
||||
{
|
||||
this.qualifier = qualifier;
|
||||
this.argumentList = argumentList;
|
||||
@@ -17,6 +18,125 @@ namespace Semmle.Extraction.CSharp.Entities.Expressions
|
||||
private readonly ExpressionSyntax qualifier;
|
||||
private readonly BracketedArgumentListSyntax argumentList;
|
||||
|
||||
|
||||
private ISymbol? GetTargetSymbol()
|
||||
{
|
||||
return Context.GetSymbolInfo(base.Syntax).Symbol;
|
||||
}
|
||||
|
||||
private static void SetExprArgument(TextWriter trapFile, Expression left, Expression right)
|
||||
{
|
||||
trapFile.expr_argument(left, 0);
|
||||
trapFile.expr_argument(right, 0);
|
||||
}
|
||||
|
||||
private Expression MakeZeroFromEndExpression(IExpressionParentEntity parent, int child)
|
||||
{
|
||||
var info = new ExpressionInfo(
|
||||
Context,
|
||||
AnnotatedTypeSymbol.CreateNotAnnotated(Context.Compilation.GetSpecialType(SpecialType.System_Int32)),
|
||||
Location,
|
||||
ExprKind.INDEX,
|
||||
parent,
|
||||
child,
|
||||
isCompilerGenerated: true,
|
||||
null);
|
||||
|
||||
var index = new Expression(info);
|
||||
|
||||
MakeZeroLiteral(index, 0);
|
||||
return index;
|
||||
}
|
||||
|
||||
private Expression MakeZeroLiteral(IExpressionParentEntity parent, int child)
|
||||
{
|
||||
return Literal.CreateGenerated(Context, parent, child, Context.Compilation.GetSpecialType(SpecialType.System_Int32), 0, Location);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// It is assumed that either the input is
|
||||
/// 1. A normal expression that can be used as endpoint (e.g a constant like "3").
|
||||
/// 2. An index expression indicating that we should read from the end (e.g "^1").
|
||||
/// </summary>
|
||||
/// <param name="syntax">The syntax node representing the range endpoint.</param>
|
||||
/// <param name="parent">The parent expression entity.</param>
|
||||
/// <param name="child">The child index within the parent.</param>
|
||||
/// <returns>An expression representing the endpoint of a range to be used in conjunction with a slice operation.</returns>
|
||||
private Expression MakeFromRangeEndpoint(ExpressionSyntax syntax, IExpressionParentEntity parent, int child)
|
||||
{
|
||||
var info = new ExpressionNodeInfo(Context, syntax, parent, child);
|
||||
|
||||
return syntax.Kind() == SyntaxKind.IndexExpression
|
||||
? PrefixUnary.Create(info.SetKind(ExprKind.INDEX))
|
||||
: Factory.Create(info);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether the given method is a slice method, which is defined as a method with
|
||||
/// the name "Slice" or "Substring" and two parameters.
|
||||
/// </summary>
|
||||
/// <param name="method">The method symbol to check.</param>
|
||||
/// <returns>True if the method is a slice method; false otherwise.</returns>
|
||||
private bool IsSlice(IMethodSymbol method, out RangeExpressionSyntax? range)
|
||||
{
|
||||
range = null;
|
||||
|
||||
if (argumentList.Arguments.Count == 1)
|
||||
{
|
||||
range = argumentList.Arguments[0].Expression as RangeExpressionSyntax;
|
||||
}
|
||||
|
||||
return (method.Name == "Slice" || method.Name == "Substring")
|
||||
&& method.Parameters.Length == 2;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Populates a slice method call based on the given range.
|
||||
/// Roslyn translates indexer accesses with range expressions in the following way.
|
||||
/// 1. s[a..b] -> s.Slice(a, b - a)
|
||||
/// 2. s[..b] -> s.Slice(0, b)
|
||||
/// 3. s[a..] -> s.Slice(a, s.Length - a)
|
||||
/// 4. s[..] -> s.Slice(0, s.Length)
|
||||
/// However, it is possible that both the qualifier or the index endpoints may contain method calls.
|
||||
/// If we want to translate this accurately, we would need to introduce synthetic statements for qualifier and
|
||||
/// the endpoints, which should then be used in the slice method call.
|
||||
/// To avoid this, we translate as follows.
|
||||
/// 1. s[a..b] -> s.Slice(a, b)
|
||||
/// 2. s[..b] -> s.Slice(0, b)
|
||||
/// 3. s[a..] -> s.Slice(a, ^0)
|
||||
/// 4. s[..] -> s.Slice(0, ^0)
|
||||
///
|
||||
/// Even though index expressions can't technically be used in this way, they signal that we
|
||||
/// could perceive ^b as "length - b".
|
||||
///
|
||||
/// Call arguments are only populated when a range expression is directly available in
|
||||
/// the list of arguments.
|
||||
/// This means that cases like below are not handled.
|
||||
/// System.Range x = 1..3;
|
||||
/// s[x]
|
||||
/// </summary>
|
||||
/// <param name="trapFile">The trap file to write to.</param>
|
||||
/// <param name="slice">The slice method symbol.</param>
|
||||
/// <param name="range">The range expression syntax.</param>
|
||||
private void PopulateSlice(TextWriter trapFile, IMethodSymbol slice, RangeExpressionSyntax? range)
|
||||
{
|
||||
if (range is not null)
|
||||
{
|
||||
// Populate the call arguments
|
||||
var left = range.LeftOperand is ExpressionSyntax lsyntax
|
||||
? MakeFromRangeEndpoint(lsyntax, this, 0)
|
||||
: MakeZeroLiteral(this, 0);
|
||||
|
||||
var right = range.RightOperand is ExpressionSyntax rsyntax
|
||||
? MakeFromRangeEndpoint(rsyntax, this, 1)
|
||||
: MakeZeroFromEndExpression(this, 1);
|
||||
|
||||
SetExprArgument(trapFile, left, right);
|
||||
}
|
||||
trapFile.expr_call(this, Method.Create(Context, slice));
|
||||
}
|
||||
|
||||
protected override void PopulateExpression(TextWriter trapFile)
|
||||
{
|
||||
if (Kind == ExprKind.POINTER_INDIRECTION)
|
||||
@@ -30,11 +150,19 @@ namespace Semmle.Extraction.CSharp.Entities.Expressions
|
||||
else
|
||||
{
|
||||
Create(Context, qualifier, this, -1);
|
||||
|
||||
var target = GetTargetSymbol();
|
||||
if (target is IMethodSymbol method && IsSlice(method, out var range))
|
||||
{
|
||||
// When an indexer on a span or string is used in conjunction with a range expression, the compiler translates
|
||||
// this into a call to the "Slice" or "Substring" method.
|
||||
// In this case, we want to populate a slice/substring method call instead of an indexer access.
|
||||
PopulateSlice(trapFile, method, range);
|
||||
return;
|
||||
}
|
||||
|
||||
PopulateArguments(trapFile, argumentList, 0);
|
||||
|
||||
var symbolInfo = Context.GetSymbolInfo(base.Syntax);
|
||||
|
||||
if (symbolInfo.Symbol is IPropertySymbol indexer)
|
||||
if (target is IPropertySymbol { IsIndexer: true } indexer)
|
||||
{
|
||||
trapFile.expr_access(this, Indexer.Create(Context, indexer));
|
||||
}
|
||||
@@ -46,8 +174,11 @@ namespace Semmle.Extraction.CSharp.Entities.Expressions
|
||||
private static bool IsArray(ITypeSymbol symbol) =>
|
||||
symbol.TypeKind == Microsoft.CodeAnalysis.TypeKind.Array || symbol.IsInlineArray();
|
||||
|
||||
private static ExprKind GetKind(Context cx, ExpressionSyntax qualifier)
|
||||
private static ExprKind GetKind(Context cx, ExpressionSyntax syntax, ExpressionSyntax qualifier)
|
||||
{
|
||||
if (cx.GetSymbolInfo(syntax).Symbol is IMethodSymbol)
|
||||
return ExprKind.METHOD_INVOCATION;
|
||||
|
||||
var qualifierType = cx.GetType(qualifier);
|
||||
|
||||
// This is a compilation error, so make a guess and continue.
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
## 1.7.68
|
||||
|
||||
No user-facing changes.
|
||||
|
||||
## 1.7.67
|
||||
|
||||
No user-facing changes.
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
## 1.7.68
|
||||
|
||||
No user-facing changes.
|
||||
@@ -1,2 +1,2 @@
|
||||
---
|
||||
lastReleaseVersion: 1.7.67
|
||||
lastReleaseVersion: 1.7.68
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
name: codeql/csharp-solorigate-all
|
||||
version: 1.7.68-dev
|
||||
version: 1.7.69-dev
|
||||
groups:
|
||||
- csharp
|
||||
- solorigate
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
## 1.7.68
|
||||
|
||||
No user-facing changes.
|
||||
|
||||
## 1.7.67
|
||||
|
||||
No user-facing changes.
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
## 1.7.68
|
||||
|
||||
No user-facing changes.
|
||||
@@ -1,2 +1,2 @@
|
||||
---
|
||||
lastReleaseVersion: 1.7.67
|
||||
lastReleaseVersion: 1.7.68
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
name: codeql/csharp-solorigate-queries
|
||||
version: 1.7.68-dev
|
||||
version: 1.7.69-dev
|
||||
groups:
|
||||
- csharp
|
||||
- solorigate
|
||||
|
||||
@@ -1,3 +1,10 @@
|
||||
## 6.0.2
|
||||
|
||||
### Minor Analysis Improvements
|
||||
|
||||
* Full support for C# 14 / .NET 10. All new language features are now supported by the extractor. The QL library and data flow analysis now support the new C# 14 language constructs and include generated Models as Data (MaD) models for the .NET 10 runtime.
|
||||
* C# 14: Added support for user-defined instance increment/decrement operators.
|
||||
|
||||
## 6.0.1
|
||||
|
||||
No user-facing changes.
|
||||
|
||||
@@ -1,4 +0,0 @@
|
||||
---
|
||||
category: minorAnalysis
|
||||
---
|
||||
* C# 14: Added support for user-defined instance increment/decrement operators.
|
||||
@@ -0,0 +1,4 @@
|
||||
---
|
||||
category: minorAnalysis
|
||||
---
|
||||
* Improved extraction of range-access expressions on spans and strings (for example, `a[0..3]`). These expressions are now extracted as `Slice` (span) or `Substring` (string) calls.
|
||||
@@ -0,0 +1,4 @@
|
||||
---
|
||||
category: minorAnalysis
|
||||
---
|
||||
* Improved property and indexer call target resolution for partially overridden properties and indexers.
|
||||
@@ -0,0 +1,4 @@
|
||||
---
|
||||
category: majorAnalysis
|
||||
---
|
||||
* Added Razor Page handler method parameters (e.g., `OnGet`, `OnPost`, `OnPostAsync`) as remote flow sources, enabling security queries such as `cs/sql-injection` to detect vulnerabilities in `PageModel` subclasses.
|
||||
@@ -0,0 +1,4 @@
|
||||
---
|
||||
category: breaking
|
||||
---
|
||||
* Renamed types related to *operation* expressions. The QL classes `BinaryArithmeticOperation`, `BinaryBitwiseOperation`, and `BinaryLogicalOperation` now include compound assignments; for example, `BinaryArithmeticOperation` now includes `a += b`.
|
||||
@@ -1,4 +1,6 @@
|
||||
---
|
||||
category: minorAnalysis
|
||||
---
|
||||
## 6.0.2
|
||||
|
||||
### Minor Analysis Improvements
|
||||
|
||||
* Full support for C# 14 / .NET 10. All new language features are now supported by the extractor. The QL library and data flow analysis now support the new C# 14 language constructs and include generated Models as Data (MaD) models for the .NET 10 runtime.
|
||||
* C# 14: Added support for user-defined instance increment/decrement operators.
|
||||
@@ -1,2 +1,2 @@
|
||||
---
|
||||
lastReleaseVersion: 6.0.1
|
||||
lastReleaseVersion: 6.0.2
|
||||
|
||||
@@ -50,15 +50,15 @@ private predicate maybeUsedInElfHashFunction(Variable v, Operation xor, Operatio
|
||||
|
|
||||
add instanceof AddOperation and
|
||||
e1.getAChild*() = add.getAnOperand() and
|
||||
e1 instanceof BinaryBitwiseOperation and
|
||||
e2 = e1.(BinaryBitwiseOperation).getLeftOperand() and
|
||||
e1 instanceof BinaryBitwiseExpr and
|
||||
e2 = e1.(BinaryBitwiseExpr).getLeftOperand() and
|
||||
v = addAssign.getTargetVariable() and
|
||||
addAssign.getAChild*() = add and
|
||||
(xor instanceof BitwiseXorExpr or xor instanceof AssignXorExpr) and
|
||||
addAssign.getControlFlowNode().getASuccessor*() = xor.getControlFlowNode() and
|
||||
xorAssign.getAChild*() = xor and
|
||||
v = xorAssign.getTargetVariable() and
|
||||
(notOp instanceof UnaryBitwiseOperation or notOp instanceof AssignBitwiseOperation) and
|
||||
(notOp instanceof UnaryBitwiseOperation or notOp instanceof AssignBitwiseExpr) and
|
||||
xor.getControlFlowNode().getASuccessor*() = notOp.getControlFlowNode() and
|
||||
notAssign.getAChild*() = notOp and
|
||||
v = notAssign.getTargetVariable() and
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
name: codeql/csharp-all
|
||||
version: 6.0.2-dev
|
||||
version: 6.0.3-dev
|
||||
groups: csharp
|
||||
dbscheme: semmlecode.csharp.dbscheme
|
||||
extractor: csharp
|
||||
@@ -9,6 +9,7 @@ dependencies:
|
||||
codeql/controlflow: ${workspace}
|
||||
codeql/dataflow: ${workspace}
|
||||
codeql/mad: ${workspace}
|
||||
codeql/rangeanalysis: ${workspace}
|
||||
codeql/ssa: ${workspace}
|
||||
codeql/threat-models: ${workspace}
|
||||
codeql/tutorial: ${workspace}
|
||||
|
||||
@@ -290,7 +290,7 @@ module AssignableInternal {
|
||||
newtype TAssignableDefinition =
|
||||
TAssignmentDefinition(Assignment a) {
|
||||
not a.getLeftOperand() instanceof TupleExpr and
|
||||
not a instanceof AssignCallOperation and
|
||||
not a instanceof AssignCallExpr and
|
||||
not a instanceof AssignCoalesceExpr
|
||||
} or
|
||||
TTupleAssignmentDefinition(AssignExpr ae, Expr leaf) { tupleAssignmentDefinition(ae, leaf) } or
|
||||
@@ -324,7 +324,7 @@ module AssignableInternal {
|
||||
TAddressOfDefinition(AddressOfExpr aoe) or
|
||||
TPatternDefinition(TopLevelPatternDecl tlpd) or
|
||||
TAssignOperationDefinition(AssignOperation ao) {
|
||||
ao instanceof AssignCallOperation and not ao instanceof CompoundAssignmentOperatorCall
|
||||
ao instanceof AssignCallExpr and not ao instanceof CompoundAssignmentOperatorCall
|
||||
or
|
||||
ao instanceof AssignCoalesceExpr
|
||||
}
|
||||
|
||||
@@ -57,6 +57,28 @@ class DeclarationWithGetSetAccessors extends DeclarationWithAccessors, TopLevelE
|
||||
/** Gets the `set` accessor of this declaration, if any. */
|
||||
Setter getSetter() { result = this.getAnAccessor() }
|
||||
|
||||
/** Gets the target accessor of this declaration when used in a read context, if any. */
|
||||
Accessor getReadTarget() {
|
||||
result = this.getGetter()
|
||||
or
|
||||
not exists(this.getGetter()) and
|
||||
result = this.getOverridee().getReadTarget()
|
||||
}
|
||||
|
||||
/** Gets the target accessor of this declaration when used in a write context, if any. */
|
||||
Accessor getWriteTarget() {
|
||||
result = this.getSetter()
|
||||
or
|
||||
not exists(this.getSetter()) and
|
||||
result = this.getOverridee().getWriteTarget()
|
||||
or
|
||||
result =
|
||||
any(Getter g |
|
||||
g = this.getReadTarget() and
|
||||
g.getAnnotatedReturnType().isRef()
|
||||
)
|
||||
}
|
||||
|
||||
override DeclarationWithGetSetAccessors getOverridee() {
|
||||
result = DeclarationWithAccessors.super.getOverridee()
|
||||
}
|
||||
|
||||
@@ -912,18 +912,17 @@ module Internal {
|
||||
)
|
||||
or
|
||||
// In C#, `null + 1` has type `int?` with value `null`
|
||||
exists(BinaryOperation bo, Expr o |
|
||||
bo instanceof BinaryArithmeticOperation or
|
||||
bo instanceof AssignArithmeticOperation
|
||||
|
|
||||
result = bo and
|
||||
bo.getAnOperand() = e and
|
||||
bo.getAnOperand() = o and
|
||||
// The other operand must be provably non-null in order
|
||||
// for `only if` to hold
|
||||
nonNullValueImplied(o) and
|
||||
e != o
|
||||
)
|
||||
result =
|
||||
any(BinaryArithmeticOperation bao |
|
||||
exists(Expr o |
|
||||
bao.getAnOperand() = e and
|
||||
bao.getAnOperand() = o and
|
||||
// The other operand must be provably non-null in order
|
||||
// for `only if` to hold
|
||||
nonNullValueImplied(o) and
|
||||
e != o
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -934,10 +933,10 @@ module Internal {
|
||||
any(QualifiableExpr qe |
|
||||
qe.isConditional() and
|
||||
result = qe.getQualifier()
|
||||
) or
|
||||
)
|
||||
or
|
||||
// In C#, `null + 1` has type `int?` with value `null`
|
||||
e = any(BinaryArithmeticOperation bao | result = bao.getAnOperand()) or
|
||||
e = any(AssignArithmeticOperation aao | result = aao.getAnOperand())
|
||||
e = any(BinaryArithmeticOperation bao | result = bao.getAnOperand())
|
||||
}
|
||||
|
||||
deprecated predicate isGuard(Expr e, GuardValue val) {
|
||||
|
||||
@@ -145,6 +145,8 @@ module Ast implements AstSig<Location> {
|
||||
final private class ParameterFinal = CS::Parameter;
|
||||
|
||||
class Parameter extends ParameterFinal {
|
||||
AstNode getPattern() { result = this }
|
||||
|
||||
Expr getDefaultValue() {
|
||||
// Avoid combinatorial explosions for callables with multiple bodies
|
||||
result = unique( | | super.getDefaultValue())
|
||||
@@ -172,6 +174,10 @@ module Ast implements AstSig<Location> {
|
||||
|
||||
class DoStmt = CS::DoStmt;
|
||||
|
||||
class UntilStmt extends LoopStmt {
|
||||
UntilStmt() { none() }
|
||||
}
|
||||
|
||||
final private class FinalForStmt = CS::ForStmt;
|
||||
|
||||
class ForStmt extends FinalForStmt {
|
||||
@@ -203,7 +209,7 @@ module Ast implements AstSig<Location> {
|
||||
final private class FinalTryStmt = CS::TryStmt;
|
||||
|
||||
class TryStmt extends FinalTryStmt {
|
||||
Stmt getBody() { result = this.getBlock() }
|
||||
AstNode getBody(int index) { index = 0 and result = this.getBlock() }
|
||||
|
||||
CatchClause getCatch(int index) { result = this.getCatchClause(index) }
|
||||
|
||||
|
||||
@@ -4,67 +4,31 @@
|
||||
overlay[local?]
|
||||
module;
|
||||
|
||||
private import internal.rangeanalysis.BoundSpecific
|
||||
private import csharp as CS
|
||||
private import semmle.code.csharp.dataflow.SSA::Ssa
|
||||
private import semmle.code.csharp.dataflow.internal.rangeanalysis.ConstantUtils as CU
|
||||
private import semmle.code.csharp.dataflow.internal.rangeanalysis.RangeUtils as RU
|
||||
private import semmle.code.csharp.dataflow.internal.rangeanalysis.SsaUtils as SU
|
||||
private import codeql.rangeanalysis.Bound as SharedBound
|
||||
|
||||
private newtype TBound =
|
||||
TBoundZero() or
|
||||
TBoundSsa(SsaVariable v) { v.getSourceVariable().getType() instanceof IntegralType } or
|
||||
TBoundExpr(Expr e) {
|
||||
interestingExprBound(e) and
|
||||
not exists(SsaVariable v | e = v.getAUse())
|
||||
}
|
||||
/** Provides C#-specific definitions for bounds. */
|
||||
private module BoundDefs implements SharedBound::BoundDefinitions<CS::Location> {
|
||||
class Type = CS::Type;
|
||||
|
||||
/**
|
||||
* A bound that may be inferred for an expression plus/minus an integer delta.
|
||||
*/
|
||||
abstract class Bound extends TBound {
|
||||
/** Gets a textual representation of this bound. */
|
||||
abstract string toString();
|
||||
class SsaVariable = SU::SsaVariable;
|
||||
|
||||
/** Gets an expression that equals this bound plus `delta`. */
|
||||
abstract Expr getExpr(int delta);
|
||||
class SsaSourceVariable = SourceVariable;
|
||||
|
||||
/** Gets an expression that equals this bound. */
|
||||
Expr getExpr() { result = this.getExpr(0) }
|
||||
class Expr = CS::ControlFlowNodes::ExprNode;
|
||||
|
||||
/** Gets the location of this bound. */
|
||||
abstract Location getLocation();
|
||||
class IntegralType = CS::IntegralType;
|
||||
|
||||
class ConstantIntegerExpr = CU::ConstantIntegerExpr;
|
||||
|
||||
/** Holds if `e` is a bound expression and it is not an SSA variable read. */
|
||||
predicate interestingExprBound(Expr e) { CU::systemArrayLengthAccess(e.getExpr()) }
|
||||
}
|
||||
|
||||
/**
|
||||
* The bound that corresponds to the integer 0. This is used to represent all
|
||||
* integer bounds as bounds are always accompanied by an added integer delta.
|
||||
*/
|
||||
class ZeroBound extends Bound, TBoundZero {
|
||||
override string toString() { result = "0" }
|
||||
module BoundImpl = SharedBound::Bound<CS::Location, BoundDefs>;
|
||||
|
||||
override Expr getExpr(int delta) { result.(ConstantIntegerExpr).getIntValue() = delta }
|
||||
|
||||
override Location getLocation() { result.hasLocationInfo("", 0, 0, 0, 0) }
|
||||
}
|
||||
|
||||
/**
|
||||
* A bound corresponding to the value of an SSA variable.
|
||||
*/
|
||||
class SsaBound extends Bound, TBoundSsa {
|
||||
/** Gets the SSA variable that equals this bound. */
|
||||
SsaVariable getSsa() { this = TBoundSsa(result) }
|
||||
|
||||
override string toString() { result = this.getSsa().toString() }
|
||||
|
||||
override Expr getExpr(int delta) { result = this.getSsa().getAUse() and delta = 0 }
|
||||
|
||||
override Location getLocation() { result = this.getSsa().getLocation() }
|
||||
}
|
||||
|
||||
/**
|
||||
* A bound that corresponds to the value of a specific expression that might be
|
||||
* interesting, but isn't otherwise represented by the value of an SSA variable.
|
||||
*/
|
||||
class ExprBound extends Bound, TBoundExpr {
|
||||
override string toString() { result = this.getExpr().toString() }
|
||||
|
||||
override Expr getExpr(int delta) { this = TBoundExpr(result) and delta = 0 }
|
||||
|
||||
override Location getLocation() { result = this.getExpr().getLocation() }
|
||||
}
|
||||
import BoundImpl
|
||||
|
||||
@@ -1,22 +0,0 @@
|
||||
/**
|
||||
* Provides C#-specific definitions for bounds.
|
||||
*/
|
||||
|
||||
private import csharp as CS
|
||||
private import semmle.code.csharp.dataflow.SSA::Ssa as Ssa
|
||||
private import semmle.code.csharp.dataflow.internal.rangeanalysis.ConstantUtils as CU
|
||||
private import semmle.code.csharp.dataflow.internal.rangeanalysis.RangeUtils as RU
|
||||
private import semmle.code.csharp.dataflow.internal.rangeanalysis.SsaUtils as SU
|
||||
|
||||
class SsaVariable = SU::SsaVariable;
|
||||
|
||||
class Expr = CS::ControlFlowNodes::ExprNode;
|
||||
|
||||
class Location = CS::Location;
|
||||
|
||||
class IntegralType = CS::IntegralType;
|
||||
|
||||
class ConstantIntegerExpr = CU::ConstantIntegerExpr;
|
||||
|
||||
/** Holds if `e` is a bound expression and it is not an SSA variable read. */
|
||||
predicate interestingExprBound(Expr e) { CU::systemArrayLengthAccess(e.getExpr()) }
|
||||
@@ -124,9 +124,7 @@ private module Internal {
|
||||
TDispatchDynamicOperatorCall(DynamicOperatorCall doc) or
|
||||
TDispatchDynamicMemberAccess(DynamicMemberAccess dma) or
|
||||
TDispatchDynamicElementAccess(DynamicElementAccess dea) or
|
||||
TDispatchDynamicEventAccess(
|
||||
AssignArithmeticOperation aao, DynamicMemberAccess dma, string name
|
||||
) {
|
||||
TDispatchDynamicEventAccess(AssignArithmeticExpr aao, DynamicMemberAccess dma, string name) {
|
||||
isPotentialEventCall(aao, dma, name)
|
||||
} or
|
||||
TDispatchDynamicObjectCreation(DynamicObjectCreation doc) or
|
||||
@@ -230,7 +228,7 @@ private module Internal {
|
||||
* accessor.
|
||||
*/
|
||||
private predicate isPotentialEventCall(
|
||||
AssignArithmeticOperation aao, DynamicMemberAccess dma, string name
|
||||
AssignArithmeticExpr aao, DynamicMemberAccess dma, string name
|
||||
) {
|
||||
aao instanceof DynamicOperatorCall and
|
||||
dma = aao.getLeftOperand() and
|
||||
@@ -1397,9 +1395,7 @@ private module Internal {
|
||||
private class DispatchDynamicEventAccess extends DispatchReflectionOrDynamicCall,
|
||||
TDispatchDynamicEventAccess
|
||||
{
|
||||
override AssignArithmeticOperation getCall() {
|
||||
this = TDispatchDynamicEventAccess(result, _, _)
|
||||
}
|
||||
override AssignArithmeticExpr getCall() { this = TDispatchDynamicEventAccess(result, _, _) }
|
||||
|
||||
override string getName() { this = TDispatchDynamicEventAccess(_, _, result) }
|
||||
|
||||
|
||||
@@ -11,19 +11,27 @@ import Expr
|
||||
* (`UnaryArithmeticOperation`) or a binary arithmetic operation
|
||||
* (`BinaryArithmeticOperation`).
|
||||
*/
|
||||
class ArithmeticOperation extends Operation, @arith_op_expr {
|
||||
class ArithmeticOperation extends Operation, @arith_operation {
|
||||
override string getOperator() { none() }
|
||||
}
|
||||
|
||||
/**
|
||||
* A unary arithmetic operation. Either a unary minus operation
|
||||
* (`UnaryMinusExpr`), a unary plus operation (`UnaryPlusExpr`),
|
||||
* or a mutator operation (`MutatorOperation`).
|
||||
* A binary arithmetic operation. Either a binary arithmetic expression (`BinaryArithmeticExpr`) or
|
||||
* an arithmetic assignment expression (`AssignArithmeticExpr`).
|
||||
*/
|
||||
class UnaryArithmeticOperation extends ArithmeticOperation, UnaryOperation, @un_arith_op_expr { }
|
||||
class BinaryArithmeticOperation extends ArithmeticOperation, BinaryOperation, @bin_arith_operation {
|
||||
override string getOperator() { none() }
|
||||
}
|
||||
|
||||
/**
|
||||
* A unary minus operation, for example `-x`.
|
||||
* A unary arithmetic operation. Either a unary minus expression
|
||||
* (`UnaryMinusExpr`), a unary plus expression (`UnaryPlusExpr`),
|
||||
* or a mutator operation (`MutatorOperation`).
|
||||
*/
|
||||
class UnaryArithmeticOperation extends ArithmeticOperation, UnaryOperation, @un_arith_operation { }
|
||||
|
||||
/**
|
||||
* A unary minus expression, for example `-x`.
|
||||
*/
|
||||
class UnaryMinusExpr extends UnaryArithmeticOperation, @minus_expr {
|
||||
override string getOperator() { result = "-" }
|
||||
@@ -32,7 +40,7 @@ class UnaryMinusExpr extends UnaryArithmeticOperation, @minus_expr {
|
||||
}
|
||||
|
||||
/**
|
||||
* A unary plus operation, for example `+x`.
|
||||
* A unary plus expression, for example `+x`.
|
||||
*/
|
||||
class UnaryPlusExpr extends UnaryArithmeticOperation, @plus_expr {
|
||||
override string getOperator() { result = "+" }
|
||||
@@ -44,40 +52,40 @@ class UnaryPlusExpr extends UnaryArithmeticOperation, @plus_expr {
|
||||
* A mutator operation. Either an increment operation (`IncrementOperation`)
|
||||
* or a decrement operation (`DecrementOperation`).
|
||||
*/
|
||||
class MutatorOperation extends UnaryArithmeticOperation, @mut_op_expr { }
|
||||
class MutatorOperation extends UnaryArithmeticOperation, @mut_operation { }
|
||||
|
||||
/**
|
||||
* An increment operation. Either a postfix increment operation
|
||||
* (`PostIncrExpr`) or a prefix increment operation (`PreIncrExpr`).
|
||||
* An increment operation. Either a postfix increment expression
|
||||
* (`PostIncrExpr`) or a prefix increment expression (`PreIncrExpr`).
|
||||
*/
|
||||
class IncrementOperation extends MutatorOperation, @incr_op_expr {
|
||||
class IncrementOperation extends MutatorOperation, @incr_operation {
|
||||
override string getOperator() { result = "++" }
|
||||
}
|
||||
|
||||
/**
|
||||
* A decrement operation. Either a postfix decrement operation
|
||||
* (`PostDecrExpr`) or a prefix decrement operation (`PreDecrExpr`).
|
||||
* A decrement operation. Either a postfix decrement expression
|
||||
* (`PostDecrExpr`) or a prefix decrement expression (`PreDecrExpr`).
|
||||
*/
|
||||
class DecrementOperation extends MutatorOperation, @decr_op_expr {
|
||||
class DecrementOperation extends MutatorOperation, @decr_operation {
|
||||
override string getOperator() { result = "--" }
|
||||
}
|
||||
|
||||
/**
|
||||
* A prefix increment operation, for example `++x`.
|
||||
* A prefix increment expression, for example `++x`.
|
||||
*/
|
||||
class PreIncrExpr extends IncrementOperation, @pre_incr_expr {
|
||||
override string getAPrimaryQlClass() { result = "PreIncrExpr" }
|
||||
}
|
||||
|
||||
/**
|
||||
* A prefix decrement operation, for example `--x`.
|
||||
* A prefix decrement expression, for example `--x`.
|
||||
*/
|
||||
class PreDecrExpr extends DecrementOperation, @pre_decr_expr {
|
||||
override string getAPrimaryQlClass() { result = "PreDecrExpr" }
|
||||
}
|
||||
|
||||
/**
|
||||
* A postfix increment operation, for example `x++`.
|
||||
* A postfix increment expression, for example `x++`.
|
||||
*/
|
||||
class PostIncrExpr extends IncrementOperation, @post_incr_expr {
|
||||
override string toString() { result = "..." + this.getOperator() }
|
||||
@@ -86,7 +94,7 @@ class PostIncrExpr extends IncrementOperation, @post_incr_expr {
|
||||
}
|
||||
|
||||
/**
|
||||
* A postfix decrement operation, for example `x--`.
|
||||
* A postfix decrement expression, for example `x--`.
|
||||
*/
|
||||
class PostDecrExpr extends DecrementOperation, @post_decr_expr {
|
||||
override string toString() { result = "..." + this.getOperator() }
|
||||
@@ -95,55 +103,84 @@ class PostDecrExpr extends DecrementOperation, @post_decr_expr {
|
||||
}
|
||||
|
||||
/**
|
||||
* A binary arithmetic operation. Either an addition operation
|
||||
* (`AddExpr`), a subtraction operation (`SubExpr`), a multiplication
|
||||
* operation (`MulExpr`), a division operation (`DivExpr`), or a
|
||||
* remainder operation (`RemExpr`).
|
||||
* An addition operation, either `x + y` or `x += y`.
|
||||
*/
|
||||
class BinaryArithmeticOperation extends ArithmeticOperation, BinaryOperation, @bin_arith_op_expr {
|
||||
override string getOperator() { none() }
|
||||
class AddOperation extends BinaryArithmeticOperation, @add_operation { }
|
||||
|
||||
/**
|
||||
* A subtraction operation, either `x - y` or `x -= y`.
|
||||
*/
|
||||
class SubOperation extends BinaryArithmeticOperation, @sub_operation { }
|
||||
|
||||
/**
|
||||
* A multiplication operation, either `x * y` or `x *= y`.
|
||||
*/
|
||||
class MulOperation extends BinaryArithmeticOperation, @mul_operation { }
|
||||
|
||||
/**
|
||||
* A division operation, either `x / y` or `x /= y`.
|
||||
*/
|
||||
class DivOperation extends BinaryArithmeticOperation, @div_operation {
|
||||
/** Gets the numerator of this division operation. */
|
||||
Expr getNumerator() { result = this.getLeftOperand() }
|
||||
|
||||
/** Gets the denominator of this division operation. */
|
||||
Expr getDenominator() { result = this.getRightOperand() }
|
||||
}
|
||||
|
||||
/**
|
||||
* An addition operation, for example `x + y`.
|
||||
* A remainder operation, either `x % y` or `x %= y`.
|
||||
*/
|
||||
class AddExpr extends BinaryArithmeticOperation, AddOperation, @add_expr {
|
||||
class RemOperation extends BinaryArithmeticOperation, @rem_operation { }
|
||||
|
||||
/**
|
||||
* A binary arithmetic expression. Either an addition expression
|
||||
* (`AddExpr`), a subtraction expression (`SubExpr`), a multiplication
|
||||
* expression (`MulExpr`), a division expression (`DivExpr`), or a
|
||||
* remainder expression (`RemExpr`).
|
||||
*/
|
||||
class BinaryArithmeticExpr extends BinaryArithmeticOperation, @bin_arith_expr { }
|
||||
|
||||
/**
|
||||
* An addition expression, for example `x + y`.
|
||||
*/
|
||||
class AddExpr extends BinaryArithmeticExpr, AddOperation, @add_expr {
|
||||
override string getOperator() { result = "+" }
|
||||
|
||||
override string getAPrimaryQlClass() { result = "AddExpr" }
|
||||
}
|
||||
|
||||
/**
|
||||
* A subtraction operation, for example `x - y`.
|
||||
* A subtraction expression, for example `x - y`.
|
||||
*/
|
||||
class SubExpr extends BinaryArithmeticOperation, SubOperation, @sub_expr {
|
||||
class SubExpr extends BinaryArithmeticExpr, SubOperation, @sub_expr {
|
||||
override string getOperator() { result = "-" }
|
||||
|
||||
override string getAPrimaryQlClass() { result = "SubExpr" }
|
||||
}
|
||||
|
||||
/**
|
||||
* A multiplication operation, for example `x * y`.
|
||||
* A multiplication expression, for example `x * y`.
|
||||
*/
|
||||
class MulExpr extends BinaryArithmeticOperation, MulOperation, @mul_expr {
|
||||
class MulExpr extends BinaryArithmeticExpr, MulOperation, @mul_expr {
|
||||
override string getOperator() { result = "*" }
|
||||
|
||||
override string getAPrimaryQlClass() { result = "MulExpr" }
|
||||
}
|
||||
|
||||
/**
|
||||
* A division operation, for example `x / y`.
|
||||
* A division expression, for example `x / y`.
|
||||
*/
|
||||
class DivExpr extends BinaryArithmeticOperation, DivOperation, @div_expr {
|
||||
class DivExpr extends BinaryArithmeticExpr, DivOperation, @div_expr {
|
||||
override string getOperator() { result = "/" }
|
||||
|
||||
override string getAPrimaryQlClass() { result = "DivExpr" }
|
||||
}
|
||||
|
||||
/**
|
||||
* A remainder operation, for example `x % y`.
|
||||
* A remainder expression, for example `x % y`.
|
||||
*/
|
||||
class RemExpr extends BinaryArithmeticOperation, RemOperation, @rem_expr {
|
||||
class RemExpr extends BinaryArithmeticExpr, RemOperation, @rem_expr {
|
||||
override string getOperator() { result = "%" }
|
||||
|
||||
override string getAPrimaryQlClass() { result = "RemExpr" }
|
||||
|
||||
@@ -72,9 +72,9 @@ class AssignExpr extends Assignment, @simple_assign_expr {
|
||||
}
|
||||
|
||||
/**
|
||||
* An assignment operation. Either an arithmetic assignment operation
|
||||
* (`AssignArithmeticOperation`), a bitwise assignment operation
|
||||
* (`AssignBitwiseOperation`), an event assignment (`AddOrRemoveEventExpr`), or
|
||||
* An assignment operation. Either an arithmetic assignment expression
|
||||
* (`AssignArithmeticExpr`), a bitwise assignment expression
|
||||
* (`AssignBitwiseExpr`), an event assignment (`AddOrRemoveEventExpr`), or
|
||||
* a null-coalescing assignment (`AssignCoalesceExpr`).
|
||||
*/
|
||||
class AssignOperation extends Assignment, @assign_op_expr {
|
||||
@@ -94,134 +94,147 @@ class AssignOperation extends Assignment, @assign_op_expr {
|
||||
}
|
||||
|
||||
/**
|
||||
* A compound assignment operation that invokes an operator.
|
||||
* A compound assignment expression that invokes an operator.
|
||||
*
|
||||
* (1) `x += y` invokes the compound assignment operator `+=` (if it exists).
|
||||
* (2) `x += y` invokes the operator `+` and assigns `x + y` to `x`.
|
||||
*
|
||||
* Either an arithmetic assignment operation (`AssignArithmeticOperation`) or a bitwise
|
||||
* assignment operation (`AssignBitwiseOperation`).
|
||||
* Either an arithmetic assignment expression (`AssignArithmeticExpr`) or a bitwise
|
||||
* assignment expression (`AssignBitwiseExpr`).
|
||||
*/
|
||||
class AssignCallOperation extends AssignOperation, OperatorCall, QualifiableExpr,
|
||||
@assign_op_call_expr
|
||||
{
|
||||
class AssignCallExpr extends AssignOperation, OperatorCall, QualifiableExpr, @assign_op_call_expr {
|
||||
override string toString() { result = AssignOperation.super.toString() }
|
||||
}
|
||||
|
||||
/**
|
||||
* An arithmetic assignment operation. Either an addition assignment operation
|
||||
* (`AssignAddExpr`), a subtraction assignment operation (`AssignSubExpr`), a
|
||||
* multiplication assignment operation (`AssignMulExpr`), a division assignment
|
||||
* operation (`AssignDivExpr`), or a remainder assignment operation
|
||||
* (`AssignRemExpr`).
|
||||
* DEPRECATED: Use `AssignCallExpr` instead.
|
||||
*/
|
||||
class AssignArithmeticOperation extends AssignCallOperation, @assign_arith_expr { }
|
||||
deprecated class AssignCallOperation = AssignCallExpr;
|
||||
|
||||
/**
|
||||
* An addition assignment operation, for example `x += y`.
|
||||
* An arithmetic assignment expression. Either an addition assignment expression
|
||||
* (`AssignAddExpr`), a subtraction assignment expression (`AssignSubExpr`), a
|
||||
* multiplication assignment expression (`AssignMulExpr`), a division assignment
|
||||
* expression (`AssignDivExpr`), or a remainder assignment expression
|
||||
* (`AssignRemExpr`).
|
||||
*/
|
||||
class AssignAddExpr extends AssignArithmeticOperation, AddOperation, @assign_add_expr {
|
||||
class AssignArithmeticExpr extends AssignCallExpr, @assign_arith_expr { }
|
||||
|
||||
/**
|
||||
* DEPRECATED: Use `AssignArithmeticExpr` instead.
|
||||
*/
|
||||
deprecated class AssignArithmeticOperation = AssignArithmeticExpr;
|
||||
|
||||
/**
|
||||
* An addition assignment expression, for example `x += y`.
|
||||
*/
|
||||
class AssignAddExpr extends AssignArithmeticExpr, AddOperation, @assign_add_expr {
|
||||
override string getOperator() { result = "+=" }
|
||||
|
||||
override string getAPrimaryQlClass() { result = "AssignAddExpr" }
|
||||
}
|
||||
|
||||
/**
|
||||
* A subtraction assignment operation, for example `x -= y`.
|
||||
* A subtraction assignment expression, for example `x -= y`.
|
||||
*/
|
||||
class AssignSubExpr extends AssignArithmeticOperation, SubOperation, @assign_sub_expr {
|
||||
class AssignSubExpr extends AssignArithmeticExpr, SubOperation, @assign_sub_expr {
|
||||
override string getOperator() { result = "-=" }
|
||||
|
||||
override string getAPrimaryQlClass() { result = "AssignSubExpr" }
|
||||
}
|
||||
|
||||
/**
|
||||
* An multiplication assignment operation, for example `x *= y`.
|
||||
* A multiplication assignment expression, for example `x *= y`.
|
||||
*/
|
||||
class AssignMulExpr extends AssignArithmeticOperation, MulOperation, @assign_mul_expr {
|
||||
class AssignMulExpr extends AssignArithmeticExpr, MulOperation, @assign_mul_expr {
|
||||
override string getOperator() { result = "*=" }
|
||||
|
||||
override string getAPrimaryQlClass() { result = "AssignMulExpr" }
|
||||
}
|
||||
|
||||
/**
|
||||
* An division assignment operation, for example `x /= y`.
|
||||
* A division assignment expression, for example `x /= y`.
|
||||
*/
|
||||
class AssignDivExpr extends AssignArithmeticOperation, DivOperation, @assign_div_expr {
|
||||
class AssignDivExpr extends AssignArithmeticExpr, DivOperation, @assign_div_expr {
|
||||
override string getOperator() { result = "/=" }
|
||||
|
||||
override string getAPrimaryQlClass() { result = "AssignDivExpr" }
|
||||
}
|
||||
|
||||
/**
|
||||
* A remainder assignment operation, for example `x %= y`.
|
||||
* A remainder assignment expression, for example `x %= y`.
|
||||
*/
|
||||
class AssignRemExpr extends AssignArithmeticOperation, RemOperation, @assign_rem_expr {
|
||||
class AssignRemExpr extends AssignArithmeticExpr, RemOperation, @assign_rem_expr {
|
||||
override string getOperator() { result = "%=" }
|
||||
|
||||
override string getAPrimaryQlClass() { result = "AssignRemExpr" }
|
||||
}
|
||||
|
||||
/**
|
||||
* A bitwise assignment operation. Either a bitwise-and assignment
|
||||
* operation (`AssignAndExpr`), a bitwise-or assignment
|
||||
* operation (`AssignOrExpr`), a bitwise exclusive-or assignment
|
||||
* operation (`AssignXorExpr`), a left-shift assignment
|
||||
* operation (`AssignLeftShiftExpr`), or a right-shift assignment
|
||||
* operation (`AssignRightShiftExpr`), or an unsigned right-shift assignment
|
||||
* operation (`AssignUnsignedRightShiftExpr`).
|
||||
* A bitwise assignment expression. Either a bitwise-and assignment
|
||||
* expression (`AssignAndExpr`), a bitwise-or assignment
|
||||
* expression (`AssignOrExpr`), a bitwise exclusive-or assignment
|
||||
* expression (`AssignXorExpr`), a left-shift assignment
|
||||
* expression (`AssignLeftShiftExpr`), or a right-shift assignment
|
||||
* expression (`AssignRightShiftExpr`), or an unsigned right-shift assignment
|
||||
* expression (`AssignUnsignedRightShiftExpr`).
|
||||
*/
|
||||
class AssignBitwiseOperation extends AssignCallOperation, @assign_bitwise_expr { }
|
||||
class AssignBitwiseExpr extends AssignCallExpr, @assign_bitwise_expr { }
|
||||
|
||||
/**
|
||||
* A bitwise-and assignment operation, for example `x &= y`.
|
||||
* DEPRECATED: Use `AssignBitwiseExpr` instead.
|
||||
*/
|
||||
class AssignAndExpr extends AssignBitwiseOperation, BitwiseAndOperation, @assign_and_expr {
|
||||
deprecated class AssignBitwiseOperation = AssignBitwiseExpr;
|
||||
|
||||
/**
|
||||
* A bitwise-and assignment expression, for example `x &= y`.
|
||||
*/
|
||||
class AssignAndExpr extends AssignBitwiseExpr, BitwiseAndOperation, @assign_and_expr {
|
||||
override string getOperator() { result = "&=" }
|
||||
|
||||
override string getAPrimaryQlClass() { result = "AssignAndExpr" }
|
||||
}
|
||||
|
||||
/**
|
||||
* A bitwise-or assignment operation, for example `x |= y`.
|
||||
* A bitwise-or assignment expression, for example `x |= y`.
|
||||
*/
|
||||
class AssignOrExpr extends AssignBitwiseOperation, BitwiseOrOperation, @assign_or_expr {
|
||||
class AssignOrExpr extends AssignBitwiseExpr, BitwiseOrOperation, @assign_or_expr {
|
||||
override string getOperator() { result = "|=" }
|
||||
|
||||
override string getAPrimaryQlClass() { result = "AssignOrExpr" }
|
||||
}
|
||||
|
||||
/**
|
||||
* A bitwise exclusive-or assignment operation, for example `x ^= y`.
|
||||
* A bitwise exclusive-or assignment expression, for example `x ^= y`.
|
||||
*/
|
||||
class AssignXorExpr extends AssignBitwiseOperation, BitwiseXorOperation, @assign_xor_expr {
|
||||
class AssignXorExpr extends AssignBitwiseExpr, BitwiseXorOperation, @assign_xor_expr {
|
||||
override string getOperator() { result = "^=" }
|
||||
|
||||
override string getAPrimaryQlClass() { result = "AssignXorExpr" }
|
||||
}
|
||||
|
||||
/**
|
||||
* A left-shift assignment operation, for example `x <<= y`.
|
||||
* A left-shift assignment expression, for example `x <<= y`.
|
||||
*/
|
||||
class AssignLeftShiftExpr extends AssignBitwiseOperation, LeftShiftOperation, @assign_lshift_expr {
|
||||
class AssignLeftShiftExpr extends AssignBitwiseExpr, LeftShiftOperation, @assign_lshift_expr {
|
||||
override string getOperator() { result = "<<=" }
|
||||
|
||||
override string getAPrimaryQlClass() { result = "AssignLeftShiftExpr" }
|
||||
}
|
||||
|
||||
/**
|
||||
* A right-shift assignment operation, for example `x >>= y`.
|
||||
* A right-shift assignment expression, for example `x >>= y`.
|
||||
*/
|
||||
class AssignRightShiftExpr extends AssignBitwiseOperation, RightShiftOperation, @assign_rshift_expr {
|
||||
class AssignRightShiftExpr extends AssignBitwiseExpr, RightShiftOperation, @assign_rshift_expr {
|
||||
override string getOperator() { result = ">>=" }
|
||||
|
||||
override string getAPrimaryQlClass() { result = "AssignRightShiftExpr" }
|
||||
}
|
||||
|
||||
/**
|
||||
* An unsigned right-shift assignment operation, for example `x >>>= y`.
|
||||
* An unsigned right-shift assignment expression, for example `x >>>= y`.
|
||||
*/
|
||||
class AssignUnsignedRightShiftExpr extends AssignBitwiseOperation, UnsignedRightShiftOperation,
|
||||
class AssignUnsignedRightShiftExpr extends AssignBitwiseExpr, UnsignedRightShiftOperation,
|
||||
@assign_urshift_expr
|
||||
{
|
||||
override string getOperator() { result = ">>>=" }
|
||||
@@ -297,10 +310,10 @@ class RemoveEventExpr extends AddOrRemoveEventExpr, @remove_event_expr {
|
||||
}
|
||||
|
||||
/**
|
||||
* A null-coalescing assignment operation, for example `x ??= y`.
|
||||
* A null-coalescing assignment expression, for example `x ??= y`.
|
||||
*/
|
||||
class AssignCoalesceExpr extends AssignOperation, NullCoalescingOperation, @assign_coalesce_expr {
|
||||
override string toString() { result = "... ??= ..." }
|
||||
override string getOperator() { result = "??=" }
|
||||
|
||||
override string getAPrimaryQlClass() { result = "AssignCoalesceExpr" }
|
||||
}
|
||||
|
||||
@@ -10,16 +10,16 @@ import Expr
|
||||
* A bitwise operation. Either a unary bitwise operation (`UnaryBitwiseOperation`)
|
||||
* or a binary bitwise operation (`BinaryBitwiseOperation`).
|
||||
*/
|
||||
class BitwiseOperation extends Operation, @bit_expr { }
|
||||
class BitwiseOperation extends Operation, @bit_operation { }
|
||||
|
||||
/**
|
||||
* A unary bitwise operation, that is, a bitwise complement operation
|
||||
* (`ComplementExpr`).
|
||||
*/
|
||||
class UnaryBitwiseOperation extends BitwiseOperation, UnaryOperation, @un_bit_op_expr { }
|
||||
class UnaryBitwiseOperation extends BitwiseOperation, UnaryOperation, @un_bit_operation { }
|
||||
|
||||
/**
|
||||
* A bitwise complement operation, for example `~x`.
|
||||
* A bitwise complement expression, for example `~x`.
|
||||
*/
|
||||
class ComplementExpr extends UnaryBitwiseOperation, @bit_not_expr {
|
||||
override string getOperator() { result = "~" }
|
||||
@@ -28,67 +28,101 @@ class ComplementExpr extends UnaryBitwiseOperation, @bit_not_expr {
|
||||
}
|
||||
|
||||
/**
|
||||
* A binary bitwise operation. Either a bitwise-and operation
|
||||
* (`BitwiseAndExpr`), a bitwise-or operation (`BitwiseOrExpr`),
|
||||
* a bitwise exclusive-or operation (`BitwiseXorExpr`), a left-shift
|
||||
* operation (`LeftShiftExpr`), a right-shift operation (`RightShiftExpr`),
|
||||
* or an unsigned right-shift operation (`UnsignedRightShiftExpr`).
|
||||
* A binary bitwise operation. Either a binary bitwise expression (`BinaryBitwiseExpr`) or
|
||||
* a bitwise assignment expression (`AssignBitwiseExpr`).
|
||||
*/
|
||||
class BinaryBitwiseOperation extends BitwiseOperation, BinaryOperation, @bin_bit_op_expr {
|
||||
class BinaryBitwiseOperation extends BitwiseOperation, BinaryOperation, @bin_bit_operation {
|
||||
override string getOperator() { none() }
|
||||
}
|
||||
|
||||
/**
|
||||
* A left-shift operation, for example `x << y`.
|
||||
* A bitwise-and operation, either `x & y` or `x &= y`.
|
||||
*/
|
||||
class LeftShiftExpr extends BinaryBitwiseOperation, LeftShiftOperation, @lshift_expr {
|
||||
class BitwiseAndOperation extends BinaryBitwiseOperation, @and_operation { }
|
||||
|
||||
/**
|
||||
* A bitwise-or operation, either `x | y` or `x |= y`.
|
||||
*/
|
||||
class BitwiseOrOperation extends BinaryBitwiseOperation, @or_operation { }
|
||||
|
||||
/**
|
||||
* A bitwise exclusive-or operation, either `x ^ y` or `x ^= y`.
|
||||
*/
|
||||
class BitwiseXorOperation extends BinaryBitwiseOperation, @xor_operation { }
|
||||
|
||||
/**
|
||||
* A left-shift operation, either `x << y` or `x <<= y`.
|
||||
*/
|
||||
class LeftShiftOperation extends BinaryBitwiseOperation, @lshift_operation { }
|
||||
|
||||
/**
|
||||
* A right-shift operation, either `x >> y` or `x >>= y`.
|
||||
*/
|
||||
class RightShiftOperation extends BinaryBitwiseOperation, @rshift_operation { }
|
||||
|
||||
/**
|
||||
* An unsigned right-shift operation, either `x >>> y` or `x >>>= y`.
|
||||
*/
|
||||
class UnsignedRightShiftOperation extends BinaryBitwiseOperation, @urshift_operation { }
|
||||
|
||||
/**
|
||||
* A binary bitwise expression. Either a bitwise-and expression
|
||||
* (`BitwiseAndExpr`), a bitwise-or expression (`BitwiseOrExpr`),
|
||||
* a bitwise exclusive-or expression (`BitwiseXorExpr`), a left-shift
|
||||
* expression (`LeftShiftExpr`), a right-shift expression (`RightShiftExpr`),
|
||||
* or an unsigned right-shift expression (`UnsignedRightShiftExpr`).
|
||||
*/
|
||||
class BinaryBitwiseExpr extends BinaryBitwiseOperation, @bin_bit_expr { }
|
||||
|
||||
/**
|
||||
* A left-shift expression, for example `x << y`.
|
||||
*/
|
||||
class LeftShiftExpr extends BinaryBitwiseExpr, LeftShiftOperation, @lshift_expr {
|
||||
override string getOperator() { result = "<<" }
|
||||
|
||||
override string getAPrimaryQlClass() { result = "LeftShiftExpr" }
|
||||
}
|
||||
|
||||
/**
|
||||
* A right-shift operation, for example `x >> y`.
|
||||
* A right-shift expression, for example `x >> y`.
|
||||
*/
|
||||
class RightShiftExpr extends BinaryBitwiseOperation, RightShiftOperation, @rshift_expr {
|
||||
class RightShiftExpr extends BinaryBitwiseExpr, RightShiftOperation, @rshift_expr {
|
||||
override string getOperator() { result = ">>" }
|
||||
|
||||
override string getAPrimaryQlClass() { result = "RightShiftExpr" }
|
||||
}
|
||||
|
||||
/**
|
||||
* An unsigned right-shift operation, for example `x >>> y`.
|
||||
* An unsigned right-shift expression, for example `x >>> y`.
|
||||
*/
|
||||
class UnsignedRightShiftExpr extends BinaryBitwiseOperation, UnsignedRightShiftOperation,
|
||||
@urshift_expr
|
||||
{
|
||||
class UnsignedRightShiftExpr extends BinaryBitwiseExpr, UnsignedRightShiftOperation, @urshift_expr {
|
||||
override string getOperator() { result = ">>>" }
|
||||
|
||||
override string getAPrimaryQlClass() { result = "UnsignedRightShiftExpr" }
|
||||
}
|
||||
|
||||
/**
|
||||
* A bitwise-and operation, for example `x & y`.
|
||||
* A bitwise-and expression, for example `x & y`.
|
||||
*/
|
||||
class BitwiseAndExpr extends BinaryBitwiseOperation, BitwiseAndOperation, @bit_and_expr {
|
||||
class BitwiseAndExpr extends BinaryBitwiseExpr, BitwiseAndOperation, @bit_and_expr {
|
||||
override string getOperator() { result = "&" }
|
||||
|
||||
override string getAPrimaryQlClass() { result = "BitwiseAndExpr" }
|
||||
}
|
||||
|
||||
/**
|
||||
* A bitwise-or operation, for example `x | y`.
|
||||
* A bitwise-or expression, for example `x | y`.
|
||||
*/
|
||||
class BitwiseOrExpr extends BinaryBitwiseOperation, BitwiseOrOperation, @bit_or_expr {
|
||||
class BitwiseOrExpr extends BinaryBitwiseExpr, BitwiseOrOperation, @bit_or_expr {
|
||||
override string getOperator() { result = "|" }
|
||||
|
||||
override string getAPrimaryQlClass() { result = "BitwiseOrExpr" }
|
||||
}
|
||||
|
||||
/**
|
||||
* A bitwise exclusive-or operation, for example `x ^ y`.
|
||||
* A bitwise exclusive-or expression, for example `x ^ y`.
|
||||
*/
|
||||
class BitwiseXorExpr extends BinaryBitwiseOperation, BitwiseXorOperation, @bit_xor_expr {
|
||||
class BitwiseXorExpr extends BinaryBitwiseExpr, BitwiseXorOperation, @bit_xor_expr {
|
||||
override string getOperator() { result = "^" }
|
||||
|
||||
override string getAPrimaryQlClass() { result = "BitwiseXorExpr" }
|
||||
|
||||
@@ -609,7 +609,7 @@ class InstanceMutatorOperatorCall extends MutatorOperatorCall {
|
||||
* }
|
||||
* ```
|
||||
*/
|
||||
class CompoundAssignmentOperatorCall extends AssignCallOperation {
|
||||
class CompoundAssignmentOperatorCall extends AssignCallExpr {
|
||||
CompoundAssignmentOperatorCall() { this.getTarget() instanceof CompoundAssignmentOperator }
|
||||
|
||||
override Expr getArgument(int i) { result = this.getChildExpr(i + 1) and i >= 0 }
|
||||
@@ -762,20 +762,12 @@ class AccessorCall extends Call, QualifiableExpr, @call_access_expr {
|
||||
*/
|
||||
class PropertyCall extends AccessorCall, PropertyAccessExpr {
|
||||
override Accessor getReadTarget() {
|
||||
this instanceof AssignableRead and result = this.getProperty().getGetter()
|
||||
this instanceof AssignableRead and result = this.getProperty().getReadTarget()
|
||||
}
|
||||
|
||||
override Accessor getWriteTarget() {
|
||||
this instanceof AssignableWrite and
|
||||
exists(Property p | p = this.getProperty() |
|
||||
result = p.getSetter()
|
||||
or
|
||||
result =
|
||||
any(Getter g |
|
||||
g = p.getGetter() and
|
||||
g.getAnnotatedReturnType().isRef()
|
||||
)
|
||||
)
|
||||
result = this.getProperty().getWriteTarget()
|
||||
}
|
||||
|
||||
override Expr getArgument(int i) {
|
||||
@@ -806,20 +798,12 @@ class PropertyCall extends AccessorCall, PropertyAccessExpr {
|
||||
*/
|
||||
class IndexerCall extends AccessorCall, IndexerAccessExpr {
|
||||
override Accessor getReadTarget() {
|
||||
this instanceof AssignableRead and result = this.getIndexer().getGetter()
|
||||
this instanceof AssignableRead and result = this.getIndexer().getReadTarget()
|
||||
}
|
||||
|
||||
override Accessor getWriteTarget() {
|
||||
this instanceof AssignableWrite and
|
||||
exists(Indexer i | i = this.getIndexer() |
|
||||
result = i.getSetter()
|
||||
or
|
||||
result =
|
||||
any(Getter g |
|
||||
g = i.getGetter() and
|
||||
g.getAnnotatedReturnType().isRef()
|
||||
)
|
||||
)
|
||||
result = this.getIndexer().getWriteTarget()
|
||||
}
|
||||
|
||||
override Expr getArgument(int i) {
|
||||
|
||||
@@ -14,7 +14,6 @@ import Creation
|
||||
import Dynamic
|
||||
import Literal
|
||||
import LogicalOperation
|
||||
import Operation
|
||||
import semmle.code.csharp.controlflow.ControlFlowElement
|
||||
import semmle.code.csharp.Location
|
||||
import semmle.code.csharp.Stmt
|
||||
@@ -212,7 +211,7 @@ class LocalConstantDeclExpr extends LocalVariableDeclExpr {
|
||||
* (`UnaryOperation`), a binary operation (`BinaryOperation`), or a
|
||||
* ternary operation (`TernaryOperation`).
|
||||
*/
|
||||
class Operation extends Expr, @op_expr {
|
||||
class Operation extends Expr, @operation_expr {
|
||||
/** Gets the name of the operator in this operation. */
|
||||
string getOperator() { none() }
|
||||
|
||||
@@ -227,7 +226,7 @@ class Operation extends Expr, @op_expr {
|
||||
* indirection operation (`PointerIndirectionExpr`), an address-of operation
|
||||
* (`AddressOfExpr`), or a unary logical operation (`UnaryLogicalOperation`).
|
||||
*/
|
||||
class UnaryOperation extends Operation, @un_op {
|
||||
class UnaryOperation extends Operation, @un_operation {
|
||||
/** Gets the operand of this unary operation. */
|
||||
Expr getOperand() { result = this.getChild(0) }
|
||||
|
||||
@@ -241,7 +240,7 @@ class UnaryOperation extends Operation, @un_op {
|
||||
* a binary logical operation (`BinaryLogicalOperation`), or an
|
||||
* assignment (`Assignment`).
|
||||
*/
|
||||
class BinaryOperation extends Operation, @bin_op {
|
||||
class BinaryOperation extends Operation, @bin_operation {
|
||||
/** Gets the left operand of this binary operation. */
|
||||
Expr getLeftOperand() { result = this.getChild(0) }
|
||||
|
||||
@@ -264,7 +263,7 @@ class BinaryOperation extends Operation, @bin_op {
|
||||
* A ternary operation, that is, a ternary conditional operation
|
||||
* (`ConditionalExpr`).
|
||||
*/
|
||||
class TernaryOperation extends Operation, @ternary_op { }
|
||||
class TernaryOperation extends Operation, @ternary_operation { }
|
||||
|
||||
/**
|
||||
* A parenthesized expression, for example `(2 + 3)` in
|
||||
|
||||
@@ -11,14 +11,14 @@ import Expr
|
||||
* a binary logical operation (`BinaryLogicalOperation`), or a ternary logical
|
||||
* operation (`TernaryLogicalOperation`).
|
||||
*/
|
||||
class LogicalOperation extends Operation, @log_expr {
|
||||
class LogicalOperation extends Operation, @log_operation {
|
||||
override string getOperator() { none() }
|
||||
}
|
||||
|
||||
/**
|
||||
* A unary logical operation, that is, a logical 'not' (`LogicalNotExpr`).
|
||||
*/
|
||||
class UnaryLogicalOperation extends LogicalOperation, UnaryOperation, @un_log_op_expr { }
|
||||
class UnaryLogicalOperation extends LogicalOperation, UnaryOperation, @un_log_operation { }
|
||||
|
||||
/**
|
||||
* A logical 'not', for example `!String.IsNullOrEmpty(s)`.
|
||||
@@ -31,10 +31,10 @@ class LogicalNotExpr extends UnaryLogicalOperation, @log_not_expr {
|
||||
|
||||
/**
|
||||
* A binary logical operation. Either a logical 'and' (`LogicalAndExpr`),
|
||||
* a logical 'or' (`LogicalAndExpr`), or a null-coalescing operation
|
||||
* (`NullCoalescingExpr`).
|
||||
* a logical 'or' (`LogicalOrExpr`), or a null-coalescing operation
|
||||
* (`NullCoalescingOperation`).
|
||||
*/
|
||||
class BinaryLogicalOperation extends LogicalOperation, BinaryOperation, @bin_log_op_expr {
|
||||
class BinaryLogicalOperation extends LogicalOperation, BinaryOperation, @bin_log_operation {
|
||||
override string getOperator() { none() }
|
||||
}
|
||||
|
||||
@@ -57,7 +57,12 @@ class LogicalOrExpr extends BinaryLogicalOperation, @log_or_expr {
|
||||
}
|
||||
|
||||
/**
|
||||
* A null-coalescing operation, for example `s ?? ""` on line 2 in
|
||||
* A null-coalescing operation, either `x ?? y` or `x ??= y`.
|
||||
*/
|
||||
class NullCoalescingOperation extends BinaryLogicalOperation, @null_coalescing_operation { }
|
||||
|
||||
/**
|
||||
* A null-coalescing expression, for example `s ?? ""` on line 2 in
|
||||
*
|
||||
* ```csharp
|
||||
* string NonNullOrEmpty(string s) {
|
||||
@@ -65,9 +70,7 @@ class LogicalOrExpr extends BinaryLogicalOperation, @log_or_expr {
|
||||
* }
|
||||
* ```
|
||||
*/
|
||||
class NullCoalescingExpr extends BinaryLogicalOperation, NullCoalescingOperation,
|
||||
@null_coalescing_expr
|
||||
{
|
||||
class NullCoalescingExpr extends NullCoalescingOperation, @null_coalescing_expr {
|
||||
override string getOperator() { result = "??" }
|
||||
|
||||
override string getAPrimaryQlClass() { result = "NullCoalescingExpr" }
|
||||
@@ -77,7 +80,7 @@ class NullCoalescingExpr extends BinaryLogicalOperation, NullCoalescingOperation
|
||||
* A ternary logical operation, that is, a ternary conditional expression
|
||||
* (`ConditionalExpr`).
|
||||
*/
|
||||
class TernaryLogicalOperation extends LogicalOperation, TernaryOperation, @ternary_log_op_expr { }
|
||||
class TernaryLogicalOperation extends LogicalOperation, TernaryOperation, @ternary_log_operation { }
|
||||
|
||||
/**
|
||||
* A conditional expression, for example `s != null ? s.Length : -1`
|
||||
|
||||
@@ -1,71 +1,6 @@
|
||||
/**
|
||||
* Provides classes for operations that also have compound assignment forms.
|
||||
*/
|
||||
deprecated module;
|
||||
|
||||
import Expr
|
||||
|
||||
/**
|
||||
* An addition operation, either `x + y` or `x += y`.
|
||||
*/
|
||||
class AddOperation extends BinaryOperation, @add_operation { }
|
||||
|
||||
/**
|
||||
* A subtraction operation, either `x - y` or `x -= y`.
|
||||
*/
|
||||
class SubOperation extends BinaryOperation, @sub_operation { }
|
||||
|
||||
/**
|
||||
* A multiplication operation, either `x * y` or `x *= y`.
|
||||
*/
|
||||
class MulOperation extends BinaryOperation, @mul_operation { }
|
||||
|
||||
/**
|
||||
* A division operation, either `x / y` or `x /= y`.
|
||||
*/
|
||||
class DivOperation extends BinaryOperation, @div_operation {
|
||||
/** Gets the numerator of this division operation. */
|
||||
Expr getNumerator() { result = this.getLeftOperand() }
|
||||
|
||||
/** Gets the denominator of this division operation. */
|
||||
Expr getDenominator() { result = this.getRightOperand() }
|
||||
}
|
||||
|
||||
/**
|
||||
* A remainder operation, either `x % y` or `x %= y`.
|
||||
*/
|
||||
class RemOperation extends BinaryOperation, @rem_operation { }
|
||||
|
||||
/**
|
||||
* A bitwise-and operation, either `x & y` or `x &= y`.
|
||||
*/
|
||||
class BitwiseAndOperation extends BinaryOperation, @and_operation { }
|
||||
|
||||
/**
|
||||
* A bitwise-or operation, either `x | y` or `x |= y`.
|
||||
*/
|
||||
class BitwiseOrOperation extends BinaryOperation, @or_operation { }
|
||||
|
||||
/**
|
||||
* A bitwise exclusive-or operation, either `x ^ y` or `x ^= y`.
|
||||
*/
|
||||
class BitwiseXorOperation extends BinaryOperation, @xor_operation { }
|
||||
|
||||
/**
|
||||
* A left-shift operation, either `x << y` or `x <<= y`.
|
||||
*/
|
||||
class LeftShiftOperation extends BinaryOperation, @lshift_operation { }
|
||||
|
||||
/**
|
||||
* A right-shift operation, either `x >> y` or `x >>= y`.
|
||||
*/
|
||||
class RightShiftOperation extends BinaryOperation, @rshift_operation { }
|
||||
|
||||
/**
|
||||
* An unsigned right-shift operation, either `x >>> y` or `x >>>= y`.
|
||||
*/
|
||||
class UnsignedRightShiftOperation extends BinaryOperation, @urshift_operation { }
|
||||
|
||||
/**
|
||||
* A null-coalescing operation, either `x ?? y` or `x ??= y`.
|
||||
*/
|
||||
class NullCoalescingOperation extends BinaryOperation, @null_coalescing_operation { }
|
||||
|
||||
@@ -13,6 +13,7 @@ private import semmle.code.csharp.frameworks.system.web.ui.WebControls
|
||||
private import semmle.code.csharp.frameworks.WCF
|
||||
private import semmle.code.csharp.frameworks.microsoft.Owin
|
||||
private import semmle.code.csharp.frameworks.microsoft.AspNetCore
|
||||
private import semmle.code.csharp.frameworks.Razor
|
||||
private import semmle.code.csharp.dataflow.internal.ExternalFlow
|
||||
private import semmle.code.csharp.security.dataflow.flowsources.FlowSources
|
||||
|
||||
@@ -314,6 +315,22 @@ class AspNetCoreActionMethodParameter extends AspNetCoreRemoteFlowSource, DataFl
|
||||
override string getSourceType() { result = "ASP.NET Core MVC action method parameter" }
|
||||
}
|
||||
|
||||
/** A parameter to a Razor Page handler method, viewed as a source of remote user input. */
|
||||
class AspNetCorePageHandlerMethodParameter extends AspNetCoreRemoteFlowSource,
|
||||
DataFlow::ParameterNode
|
||||
{
|
||||
AspNetCorePageHandlerMethodParameter() {
|
||||
exists(Parameter p |
|
||||
p = this.getParameter() and
|
||||
p.fromSource()
|
||||
|
|
||||
p = any(PageModelClass pm).getAHandlerMethod().getAParameter()
|
||||
)
|
||||
}
|
||||
|
||||
override string getSourceType() { result = "ASP.NET Core Razor Page handler method parameter" }
|
||||
}
|
||||
|
||||
private class ExternalRemoteFlowSource extends RemoteFlowSource {
|
||||
ExternalRemoteFlowSource() { sourceNode(this, "remote") }
|
||||
|
||||
|
||||
@@ -1254,33 +1254,39 @@ case @expr.kind of
|
||||
|
||||
@delegate_creation_expr = @explicit_delegate_creation_expr | @implicit_delegate_creation_expr;
|
||||
|
||||
@bin_arith_op_expr = @mul_expr | @div_expr | @rem_expr | @add_expr | @sub_expr;
|
||||
@incr_op_expr = @pre_incr_expr | @post_incr_expr;
|
||||
@decr_op_expr = @pre_decr_expr | @post_decr_expr;
|
||||
@mut_op_expr = @incr_op_expr | @decr_op_expr;
|
||||
@un_arith_op_expr = @plus_expr | @minus_expr | @mut_op_expr;
|
||||
@arith_op_expr = @bin_arith_op_expr | @un_arith_op_expr;
|
||||
@bin_arith_expr = @mul_expr | @div_expr | @rem_expr | @add_expr | @sub_expr;
|
||||
@bin_arith_operation = @mul_operation | @div_operation | @rem_operation | @add_operation | @sub_operation;
|
||||
|
||||
@ternary_log_op_expr = @conditional_expr;
|
||||
@bin_log_op_expr = @log_and_expr | @log_or_expr | @null_coalescing_expr;
|
||||
@un_log_op_expr = @log_not_expr;
|
||||
@log_expr = @un_log_op_expr | @bin_log_op_expr | @ternary_log_op_expr;
|
||||
@incr_operation = @pre_incr_expr | @post_incr_expr;
|
||||
@decr_operation = @pre_decr_expr | @post_decr_expr;
|
||||
@mut_operation = @incr_operation | @decr_operation;
|
||||
@un_arith_operation = @plus_expr | @minus_expr | @mut_operation;
|
||||
@arith_operation = @bin_arith_operation | @un_arith_operation;
|
||||
|
||||
@bin_bit_op_expr = @bit_and_expr | @bit_or_expr | @bit_xor_expr | @lshift_expr
|
||||
| @rshift_expr | @urshift_expr;
|
||||
@un_bit_op_expr = @bit_not_expr;
|
||||
@bit_expr = @un_bit_op_expr | @bin_bit_op_expr;
|
||||
@ternary_log_operation = @conditional_expr;
|
||||
@bin_log_operation = @log_and_expr | @log_or_expr | @null_coalescing_operation;
|
||||
@un_log_operation = @log_not_expr;
|
||||
@log_operation = @un_log_operation | @bin_log_operation | @ternary_log_operation;
|
||||
|
||||
@bin_bit_expr = @bit_and_expr | @bit_or_expr | @bit_xor_expr | @lshift_expr
|
||||
| @rshift_expr | @urshift_expr;
|
||||
@bin_bit_operation = @and_operation | @or_operation | @xor_operation | @lshift_operation
|
||||
| @rshift_operation | @urshift_operation;
|
||||
@un_bit_expr = @bit_not_expr;
|
||||
@un_bit_operation = @un_bit_expr;
|
||||
@bit_expr = @un_bit_expr | @bin_bit_expr;
|
||||
@bit_operation = @un_bit_operation | @bin_bit_operation;
|
||||
|
||||
@equality_op_expr = @eq_expr | @ne_expr;
|
||||
@rel_op_expr = @gt_expr | @lt_expr| @ge_expr | @le_expr;
|
||||
@comp_expr = @equality_op_expr | @rel_op_expr;
|
||||
|
||||
@op_expr = @un_op | @bin_op | @ternary_op;
|
||||
@operation_expr = @un_operation | @bin_operation | @ternary_operation;
|
||||
|
||||
@ternary_op = @ternary_log_op_expr;
|
||||
@bin_op = @assign_expr | @bin_arith_op_expr | @bin_log_op_expr | @bin_bit_op_expr | @comp_expr;
|
||||
@un_op = @un_arith_op_expr | @un_log_op_expr | @un_bit_op_expr | @sizeof_expr
|
||||
| @pointer_indirection_expr | @address_of_expr;
|
||||
@ternary_operation = @ternary_log_operation;
|
||||
@bin_operation = @assign_expr | @bin_arith_operation | @bin_log_operation | @bin_bit_operation | @comp_expr;
|
||||
@un_operation = @un_arith_operation | @un_log_operation | @un_bit_operation | @sizeof_expr
|
||||
| @pointer_indirection_expr | @address_of_expr;
|
||||
|
||||
@anonymous_function_expr = @lambda_expr | @anonymous_method_expr;
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user