Skip to content

Commit 821bd1f

Browse files
committed
Merge branch 'main' into redsun82/kotlin
2 parents eab940c + bd6e233 commit 821bd1f

File tree

352 files changed

+8248
-8990
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

352 files changed

+8248
-8990
lines changed

.bazelrc

+4-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,8 @@ common --override_module=semmle_code=%workspace%/misc/bazel/semmle_code_stub
1111
build --repo_env=CC=clang --repo_env=CXX=clang++
1212

1313
build:linux --cxxopt=-std=c++20
14-
build:macos --cxxopt=-std=c++20 --cpu=darwin_x86_64
14+
# we currently cannot built the swift extractor for ARM
15+
build:macos --cxxopt=-std=c++20 --copt=-arch --copt=x86_64 --linkopt=-arch --linkopt=x86_64
1516
build:windows --cxxopt=/std:c++20 --cxxopt=/Zc:preprocessor
1617

1718
# this requires developer mode, but is required to have pack installer functioning
@@ -21,4 +22,6 @@ common --enable_runfiles
2122
common --registry=file:///%workspace%/misc/bazel/registry
2223
common --registry=https://bcr.bazel.build
2324

25+
common --@rules_dotnet//dotnet/settings:strict_deps=false
26+
2427
try-import %workspace%/local.bazelrc

.bazelrc.internal

+6
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,9 @@
22

33
common --registry=file:///%workspace%/ql/misc/bazel/registry
44
common --registry=https://bcr.bazel.build
5+
6+
# See bazelbuild/rules_dotnet#413: strict_deps in C# also appliy to 3rd-party deps, and when we pull
7+
# in (for example) the xunit package, there's no code in this at all, it just depends transitively on
8+
# its implementation packages without providing any code itself.
9+
# We either can depend on internal implementation details, or turn of strict deps.
10+
common --@rules_dotnet//dotnet/settings:strict_deps=false

.gitattributes

+2
Original file line numberDiff line numberDiff line change
@@ -79,3 +79,5 @@
7979
/csharp/paket.lock linguist-generated=true
8080
# needs eol=crlf, as `paket` touches this file and saves it as crlf
8181
/csharp/.paket/Paket.Restore.targets linguist-generated=true eol=crlf
82+
/csharp/paket.main.bzl linguist-generated=true
83+
/csharp/paket.main_extension.bzl linguist-generated=true

.github/workflows/build-ripunzip.yml

+74
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
name: Build runzip
2+
3+
on:
4+
workflow_dispatch:
5+
inputs:
6+
ripunzip-version:
7+
description: "what reference to checktout from google/runzip"
8+
required: false
9+
default: v1.2.1
10+
openssl-version:
11+
description: "what reference to checkout from openssl/openssl for Linux"
12+
required: false
13+
default: openssl-3.3.0
14+
15+
jobs:
16+
build:
17+
strategy:
18+
fail-fast: false
19+
matrix:
20+
os: [ubuntu-20.04, macos-12, windows-2019]
21+
runs-on: ${{ matrix.os }}
22+
steps:
23+
- uses: actions/checkout@v4
24+
with:
25+
repository: google/ripunzip
26+
ref: ${{ inputs.ripunzip-version }}
27+
# we need to avoid ripunzip dynamically linking into libssl
28+
# see https://github.com/sfackler/rust-openssl/issues/183
29+
- if: runner.os == 'Linux'
30+
name: checkout openssl
31+
uses: actions/checkout@v4
32+
with:
33+
repository: openssl/openssl
34+
path: openssl
35+
ref: ${{ inputs.openssl-version }}
36+
- if: runner.os == 'Linux'
37+
name: build and install openssl with fPIC
38+
shell: bash
39+
working-directory: openssl
40+
run: |
41+
./config -fPIC --prefix=$HOME/.local --openssldir=$HOME/.local/ssl
42+
make -j $(nproc)
43+
make install_sw -j $(nproc)
44+
- if: runner.os == 'Linux'
45+
name: build (linux)
46+
shell: bash
47+
run: |
48+
env OPENSSL_LIB_DIR=$HOME/.local/lib64 OPENSSL_INCLUDE_DIR=$HOME/.local/include OPENSSL_STATIC=yes cargo build --release
49+
mv target/release/ripunzip ripunzip-linux
50+
- if: runner.os == 'Windows'
51+
name: build (windows)
52+
shell: bash
53+
run: |
54+
cargo build --release
55+
mv target/release/ripunzip ripunzip-windows
56+
- name: build (macOS)
57+
if: runner.os == 'macOS'
58+
shell: bash
59+
run: |
60+
rustup target install x86_64-apple-darwin
61+
rustup target install aarch64-apple-darwin
62+
cargo build --target x86_64-apple-darwin --release
63+
cargo build --target aarch64-apple-darwin --release
64+
lipo -create -output ripunzip-macos \
65+
-arch x86_64 target/x86_64-apple-darwin/release/ripunzip \
66+
-arch arm64 target/aarch64-apple-darwin/release/ripunzip
67+
- uses: actions/upload-artifact@v4
68+
with:
69+
name: ripunzip-${{ runner.os }}
70+
path: ripunzip-*
71+
- name: Check built binary
72+
shell: bash
73+
run: |
74+
./ripunzip-* --version

BUILD.bazel

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
exports_files(["LICENSE"])

MODULE.bazel

+10
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,19 @@ bazel_dep(name = "nlohmann_json", version = "3.11.3", repo_name = "json")
2424
bazel_dep(name = "fmt", version = "10.0.0")
2525
bazel_dep(name = "rules_kotlin", version = "1.9.4-codeql.1")
2626
bazel_dep(name = "gazelle", version = "0.36.0")
27+
bazel_dep(name = "rules_dotnet", version = "0.15.1")
2728

2829
bazel_dep(name = "buildifier_prebuilt", version = "6.4.0", dev_dependency = True)
2930

31+
dotnet = use_extension("@rules_dotnet//dotnet:extensions.bzl", "dotnet")
32+
dotnet.toolchain(dotnet_version = "8.0.101")
33+
use_repo(dotnet, "dotnet_toolchains")
34+
35+
register_toolchains("@dotnet_toolchains//:all")
36+
37+
csharp_main_extension = use_extension("//csharp:paket.main_extension.bzl", "main_extension")
38+
use_repo(csharp_main_extension, "paket.main")
39+
3040
pip = use_extension("@rules_python//python/extensions:pip.bzl", "pip")
3141
pip.parse(
3242
hub_name = "codegen_deps",

config/identical-files.json

+4
Original file line numberDiff line numberDiff line change
@@ -364,5 +364,9 @@
364364
"Python model summaries test extension": [
365365
"python/ql/test/library-tests/dataflow/model-summaries/InlineTaintTest.ext.yml",
366366
"python/ql/test/library-tests/dataflow/model-summaries/NormalDataflowTest.ext.yml"
367+
],
368+
"shared tree-sitter extractor cargo.toml": [
369+
"shared/tree-sitter-extractor/Cargo.toml",
370+
"ruby/extractor/codeql-extractor-fake-crate/Cargo.toml"
367371
]
368372
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
---
2+
category: breaking
3+
---
4+
* CodeQL package management is now generally available, and all GitHub-produced CodeQL packages have had their version numbers increased to 1.0.0.

cpp/ql/lib/qlpack.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
name: codeql/cpp-all
2-
version: 0.13.2-dev
2+
version: 1.0.0-dev
33
groups: cpp
44
dbscheme: semmlecode.cpp.dbscheme
55
extractor: cpp

cpp/ql/lib/semmle/code/cpp/controlflow/IRGuards.qll

+104-39
Original file line numberDiff line numberDiff line change
@@ -565,7 +565,7 @@ class IRGuardCondition extends Instruction {
565565
/** Holds if (determined by this guard) `op == k` evaluates to `areEqual` if this expression evaluates to `value`. */
566566
cached
567567
predicate comparesEq(Operand op, int k, boolean areEqual, AbstractValue value) {
568-
compares_eq(this, op, k, areEqual, value)
568+
unary_compares_eq(this, op, k, areEqual, false, value)
569569
}
570570

571571
/**
@@ -586,7 +586,7 @@ class IRGuardCondition extends Instruction {
586586
cached
587587
predicate ensuresEq(Operand op, int k, IRBlock block, boolean areEqual) {
588588
exists(AbstractValue value |
589-
compares_eq(this, op, k, areEqual, value) and this.valueControls(block, value)
589+
unary_compares_eq(this, op, k, areEqual, false, value) and this.valueControls(block, value)
590590
)
591591
}
592592

@@ -611,7 +611,7 @@ class IRGuardCondition extends Instruction {
611611
cached
612612
predicate ensuresEqEdge(Operand op, int k, IRBlock pred, IRBlock succ, boolean areEqual) {
613613
exists(AbstractValue value |
614-
compares_eq(this, op, k, areEqual, value) and
614+
unary_compares_eq(this, op, k, areEqual, false, value) and
615615
this.valueControlsEdge(pred, succ, value)
616616
)
617617
}
@@ -737,26 +737,66 @@ private predicate compares_eq(
737737
)
738738
}
739739

740-
/** Holds if `op == k` is `areEqual` given that `test` is equal to `value`. */
741-
private predicate compares_eq(
742-
Instruction test, Operand op, int k, boolean areEqual, AbstractValue value
740+
/**
741+
* Holds if `op == k` is `areEqual` given that `test` is equal to `value`.
742+
*
743+
* Many internal predicates in this file have a `inNonZeroCase` column.
744+
* Ideally, the `k` column would be a type such as `Option<int>::Option`, to
745+
* represent whether we have a concrete value `k` such that `op == k`, or whether
746+
* we only know that `op != 0`.
747+
* However, cannot instantiate `Option` with an infinite type. Thus the boolean
748+
* `inNonZeroCase` is used to distinquish the `Some` (where we have a concrete
749+
* value `k`) and `None` cases (where we only know that `op != 0`).
750+
*
751+
* Thus, if `inNonZeroCase = true` then `op != 0` and the value of `k` is
752+
* meaningless.
753+
*
754+
* To see why `inNonZeroCase` is needed consider the following C program:
755+
* ```c
756+
* char* p = ...;
757+
* if(p) {
758+
* use(p);
759+
* }
760+
* ```
761+
* in C++ there would be an int-to-bool conversion on `p`. However, since C
762+
* does not have booleans there is no conversion. We want to be able to
763+
* conclude that `p` is non-zero in the true branch, so we need to give `k`
764+
* some value. However, simply setting `k = 1` would make the rest of the
765+
* analysis think that `k == 1` holds inside the branch. So we distinquish
766+
* between the above case and
767+
* ```c
768+
* if(p == 1) {
769+
* use(p)
770+
* }
771+
* ```
772+
* by setting `inNonZeroCase` to `true` in the former case, but not in the
773+
* latter.
774+
*/
775+
private predicate unary_compares_eq(
776+
Instruction test, Operand op, int k, boolean areEqual, boolean inNonZeroCase, AbstractValue value
743777
) {
744778
/* The simple case where the test *is* the comparison so areEqual = testIsTrue xor eq. */
745-
exists(AbstractValue v | simple_comparison_eq(test, op, k, v) |
779+
exists(AbstractValue v | unary_simple_comparison_eq(test, op, k, inNonZeroCase, v) |
746780
areEqual = true and value = v
747781
or
748782
areEqual = false and value = v.getDualValue()
749783
)
750784
or
751-
complex_eq(test, op, k, areEqual, value)
785+
unary_complex_eq(test, op, k, areEqual, inNonZeroCase, value)
752786
or
753787
/* (x is true => (op == k)) => (!x is false => (op == k)) */
754-
exists(AbstractValue dual | value = dual.getDualValue() |
755-
compares_eq(test.(LogicalNotInstruction).getUnary(), op, k, areEqual, dual)
788+
exists(AbstractValue dual, boolean inNonZeroCase0 |
789+
value = dual.getDualValue() and
790+
unary_compares_eq(test.(LogicalNotInstruction).getUnary(), op, k, inNonZeroCase0, areEqual, dual)
791+
|
792+
k = 0 and inNonZeroCase = inNonZeroCase0
793+
or
794+
k != 0 and inNonZeroCase = true
756795
)
757796
or
758797
// ((test is `areEqual` => op == const + k2) and const == `k1`) =>
759798
// test is `areEqual` => op == k1 + k2
799+
inNonZeroCase = false and
760800
exists(int k1, int k2, ConstantInstruction const |
761801
compares_eq(test, op, const.getAUse(), k2, areEqual, value) and
762802
int_value(const) = k1 and
@@ -781,35 +821,53 @@ private predicate simple_comparison_eq(
781821
value.(BooleanValue).getValue() = false
782822
}
783823

784-
/** Rearrange various simple comparisons into `op == k` form. */
785-
private predicate simple_comparison_eq(Instruction test, Operand op, int k, AbstractValue value) {
824+
/**
825+
* Holds if `test` is an instruction that is part of test that eventually is
826+
* used in a conditional branch.
827+
*/
828+
private predicate relevantUnaryComparison(Instruction test) {
829+
not test instanceof CompareInstruction and
830+
exists(IRType type, ConditionalBranchInstruction branch |
831+
type instanceof IRAddressType or type instanceof IRIntegerType
832+
|
833+
type = test.getResultIRType() and
834+
branch.getCondition() = test
835+
)
836+
or
837+
exists(LogicalNotInstruction logicalNot |
838+
relevantUnaryComparison(logicalNot) and
839+
test = logicalNot.getUnary()
840+
)
841+
}
842+
843+
/**
844+
* Rearrange various simple comparisons into `op == k` form.
845+
*/
846+
private predicate unary_simple_comparison_eq(
847+
Instruction test, Operand op, int k, boolean inNonZeroCase, AbstractValue value
848+
) {
786849
exists(SwitchInstruction switch, CaseEdge case |
787850
test = switch.getExpression() and
788851
op.getDef() = test and
789852
case = value.(MatchValue).getCase() and
790853
exists(switch.getSuccessor(case)) and
791-
case.getValue().toInt() = k
854+
case.getValue().toInt() = k and
855+
inNonZeroCase = false
792856
)
793857
or
794858
// There's no implicit CompareInstruction in files compiled as C since C
795859
// doesn't have implicit boolean conversions. So instead we check whether
796860
// there's a branch on a value of pointer or integer type.
797-
exists(ConditionalBranchInstruction branch, IRType type |
798-
not test instanceof CompareInstruction and
799-
type = test.getResultIRType() and
800-
(type instanceof IRAddressType or type instanceof IRIntegerType) and
801-
test = branch.getCondition() and
802-
op.getDef() = test
803-
|
804-
// We'd like to also include a case such as:
805-
// ```
806-
// k = 1 and
807-
// value.(BooleanValue).getValue() = true
808-
// ```
809-
// but all we know is that the value is non-zero in the true branch.
810-
// So we can only conclude something in the false branch.
861+
relevantUnaryComparison(test) and
862+
op.getDef() = test and
863+
(
864+
k = 1 and
865+
value.(BooleanValue).getValue() = true and
866+
inNonZeroCase = true
867+
or
811868
k = 0 and
812-
value.(BooleanValue).getValue() = false
869+
value.(BooleanValue).getValue() = false and
870+
inNonZeroCase = false
813871
)
814872
}
815873

@@ -821,12 +879,12 @@ private predicate complex_eq(
821879
add_eq(cmp, left, right, k, areEqual, value)
822880
}
823881

824-
private predicate complex_eq(
825-
Instruction test, Operand op, int k, boolean areEqual, AbstractValue value
882+
private predicate unary_complex_eq(
883+
Instruction test, Operand op, int k, boolean areEqual, boolean inNonZeroCase, AbstractValue value
826884
) {
827-
sub_eq(test, op, k, areEqual, value)
885+
unary_sub_eq(test, op, k, areEqual, inNonZeroCase, value)
828886
or
829-
add_eq(test, op, k, areEqual, value)
887+
unary_add_eq(test, op, k, areEqual, inNonZeroCase, value)
830888
}
831889

832890
/*
@@ -1090,16 +1148,20 @@ private predicate sub_eq(
10901148
}
10911149

10921150
// op - x == c => op == (c+x)
1093-
private predicate sub_eq(Instruction test, Operand op, int k, boolean areEqual, AbstractValue value) {
1151+
private predicate unary_sub_eq(
1152+
Instruction test, Operand op, int k, boolean areEqual, boolean inNonZeroCase, AbstractValue value
1153+
) {
1154+
inNonZeroCase = false and
10941155
exists(SubInstruction sub, int c, int x |
1095-
compares_eq(test, sub.getAUse(), c, areEqual, value) and
1156+
unary_compares_eq(test, sub.getAUse(), c, areEqual, inNonZeroCase, value) and
10961157
op = sub.getLeftOperand() and
10971158
x = int_value(sub.getRight()) and
10981159
k = c + x
10991160
)
11001161
or
1162+
inNonZeroCase = false and
11011163
exists(PointerSubInstruction sub, int c, int x |
1102-
compares_eq(test, sub.getAUse(), c, areEqual, value) and
1164+
unary_compares_eq(test, sub.getAUse(), c, areEqual, inNonZeroCase, value) and
11031165
op = sub.getLeftOperand() and
11041166
x = int_value(sub.getRight()) and
11051167
k = c + x
@@ -1153,11 +1215,13 @@ private predicate add_eq(
11531215
}
11541216

11551217
// left + x == right + c => left == right + (c-x)
1156-
private predicate add_eq(
1157-
Instruction test, Operand left, int k, boolean areEqual, AbstractValue value
1218+
private predicate unary_add_eq(
1219+
Instruction test, Operand left, int k, boolean areEqual, boolean inNonZeroCase,
1220+
AbstractValue value
11581221
) {
1222+
inNonZeroCase = false and
11591223
exists(AddInstruction lhs, int c, int x |
1160-
compares_eq(test, lhs.getAUse(), c, areEqual, value) and
1224+
unary_compares_eq(test, lhs.getAUse(), c, areEqual, inNonZeroCase, value) and
11611225
(
11621226
left = lhs.getLeftOperand() and x = int_value(lhs.getRight())
11631227
or
@@ -1166,8 +1230,9 @@ private predicate add_eq(
11661230
k = c - x
11671231
)
11681232
or
1233+
inNonZeroCase = false and
11691234
exists(PointerAddInstruction lhs, int c, int x |
1170-
compares_eq(test, lhs.getAUse(), c, areEqual, value) and
1235+
unary_compares_eq(test, lhs.getAUse(), c, areEqual, inNonZeroCase, value) and
11711236
(
11721237
left = lhs.getLeftOperand() and x = int_value(lhs.getRight())
11731238
or

0 commit comments

Comments
 (0)