Skip to content

Commit 08ce03c

Browse files
committed
Merge branch 'main' into explicit-this
2 parents f0c5a80 + 3bab8c6 commit 08ce03c

File tree

455 files changed

+22622
-4212
lines changed

Some content is hidden

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

455 files changed

+22622
-4212
lines changed

.codeqlmanifest.json

+16-11
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,16 @@
1-
{ "provide": [ "ruby/.codeqlmanifest.json",
2-
"*/ql/src/qlpack.yml",
3-
"*/ql/lib/qlpack.yml",
4-
"*/ql/test/qlpack.yml",
5-
"cpp/ql/test/query-tests/Security/CWE/CWE-190/semmle/tainted/qlpack.yml",
6-
"*/ql/examples/qlpack.yml",
7-
"*/upgrades/qlpack.yml",
8-
"javascript/ql/experimental/adaptivethreatmodeling/lib/qlpack.yml",
9-
"javascript/ql/experimental/adaptivethreatmodeling/src/qlpack.yml",
10-
"misc/legacy-support/*/qlpack.yml",
11-
"misc/suite-helpers/qlpack.yml" ] }
1+
{
2+
"provide": [
3+
"*/ql/src/qlpack.yml",
4+
"*/ql/lib/qlpack.yml",
5+
"*/ql/test/qlpack.yml",
6+
"*/ql/examples/qlpack.yml",
7+
"*/upgrades/qlpack.yml",
8+
"cpp/ql/test/query-tests/Security/CWE/CWE-190/semmle/tainted/qlpack.yml",
9+
"javascript/ql/experimental/adaptivethreatmodeling/lib/qlpack.yml",
10+
"javascript/ql/experimental/adaptivethreatmodeling/src/qlpack.yml",
11+
"misc/legacy-support/*/qlpack.yml",
12+
"misc/suite-helpers/qlpack.yml",
13+
"ruby/ql/consistency-queries/qlpack.yml",
14+
"ruby/extractor-pack/codeql-extractor.yml"
15+
]
16+
}

.github/workflows/ruby-build.yml

-10
Original file line numberDiff line numberDiff line change
@@ -102,16 +102,6 @@ jobs:
102102
PACK_FOLDER=$(readlink -f target/packs/codeql/ruby-queries/*)
103103
codeql/codeql generate query-help --format=sarifv2.1.0 --output="${PACK_FOLDER}/rules.sarif" ql/src
104104
(cd ql/src; find queries \( -name '*.qhelp' -o -name '*.rb' -o -name '*.erb' \) -exec bash -c 'mkdir -p "'"${PACK_FOLDER}"'/$(dirname "{}")"' \; -exec cp "{}" "${PACK_FOLDER}/{}" \;)
105-
- name: Compile with previous CodeQL versions
106-
run: |
107-
for version in $(gh release list --repo https://github.com/github/codeql-cli-binaries | cut -f 1 | sort --version-sort | tail -3 | head -2); do
108-
rm -f codeql-linux64.zip
109-
gh release download --repo https://github.com/github/codeql-cli-binaries --pattern codeql-linux64.zip "$version"
110-
rm -rf codeql; unzip -q codeql-linux64.zip
111-
codeql/codeql query compile target/packs/*
112-
done
113-
env:
114-
GITHUB_TOKEN: ${{ github.token }}
115105
- uses: actions/upload-artifact@v2
116106
with:
117107
name: codeql-ruby-queries

.github/workflows/ruby-qltest.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ jobs:
3232
- uses: ./ruby/actions/create-extractor-pack
3333
- name: Run QL tests
3434
run: |
35-
codeql test run --check-databases --check-unused-labels --check-repeated-labels --check-redefined-labels --check-use-before-definition --search-path "${{ github.workspace }}/ruby" --additional-packs "${{ github.workspace }}" --consistency-queries ql/consistency-queries ql/test
35+
codeql test run --check-databases --check-unused-labels --check-repeated-labels --check-redefined-labels --check-use-before-definition --consistency-queries ql/consistency-queries ql/test
3636
env:
3737
GITHUB_TOKEN: ${{ github.token }}
3838
- name: Check QL formatting

.gitignore

+3
Original file line numberDiff line numberDiff line change
@@ -27,3 +27,6 @@ csharp/extractor/Semmle.Extraction.CSharp.Driver/Properties/launchSettings.json
2727

2828
# Avoid committing cached package components
2929
.codeql
30+
31+
# Compiled class file
32+
*.class

config/identical-files.json

+9-3
Original file line numberDiff line numberDiff line change
@@ -460,9 +460,10 @@
460460
"javascript/ql/lib/semmle/javascript/security/internal/SensitiveDataHeuristics.qll",
461461
"python/ql/lib/semmle/python/security/internal/SensitiveDataHeuristics.qll"
462462
],
463-
"ReDoS Util Python/JS": [
463+
"ReDoS Util Python/JS/Ruby": [
464464
"javascript/ql/lib/semmle/javascript/security/performance/ReDoSUtil.qll",
465-
"python/ql/lib/semmle/python/security/performance/ReDoSUtil.qll"
465+
"python/ql/lib/semmle/python/security/performance/ReDoSUtil.qll",
466+
"ruby/ql/lib/codeql/ruby/security/performance/ReDoSUtil.qll"
466467
],
467468
"ReDoS Exponential Python/JS": [
468469
"javascript/ql/lib/semmle/javascript/security/performance/ExponentialBackTracking.qll",
@@ -471,7 +472,12 @@
471472
"ReDoS Polynomial Python/JS": [
472473
"javascript/ql/lib/semmle/javascript/security/performance/SuperlinearBackTracking.qll",
473474
"python/ql/lib/semmle/python/security/performance/SuperlinearBackTracking.qll",
474-
"ruby/ql/lib/codeql/ruby/regexp/SuperlinearBackTracking.qll"
475+
"ruby/ql/lib/codeql/ruby/security/performance/SuperlinearBackTracking.qll"
476+
],
477+
"BadTagFilterQuery Python/JS/Ruby": [
478+
"javascript/ql/lib/semmle/javascript/security/BadTagFilterQuery.qll",
479+
"python/ql/lib/semmle/python/security/BadTagFilterQuery.qll",
480+
"ruby/ql/lib/codeql/ruby/security/BadTagFilterQuery.qll"
475481
],
476482
"CFG": [
477483
"csharp/ql/lib/semmle/code/csharp/controlflow/internal/ControlFlowGraphImplShared.qll",
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
lgtm,codescanning
2+
* A new query `cpp/non-https-url` has been added for C/C++. The query flags uses of `http` URLs that might be better replaced with `https`.

cpp/ql/lib/semmle/code/cpp/commons/Printf.qll

+68-30
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ import semmle.code.cpp.Type
66
import semmle.code.cpp.commons.CommonType
77
import semmle.code.cpp.commons.StringAnalysis
88
import semmle.code.cpp.models.interfaces.FormattingFunction
9+
private import semmle.code.cpp.rangeanalysis.SimpleRangeAnalysis
10+
private import semmle.code.cpp.rangeanalysis.RangeAnalysisUtils
911

1012
class PrintfFormatAttribute extends FormatAttribute {
1113
PrintfFormatAttribute() { this.getArchetype() = ["printf", "__printf__"] }
@@ -268,6 +270,18 @@ class FormattingFunctionCall extends Expr {
268270
}
269271
}
270272

273+
/**
274+
* Gets the number of digits required to represent the integer represented by `f`.
275+
*
276+
* `f` is assumed to be nonnegative.
277+
*/
278+
bindingset[f]
279+
private int lengthInBase10(float f) {
280+
f = 0 and result = 1
281+
or
282+
result = f.log10().floor() + 1
283+
}
284+
271285
/**
272286
* A class to represent format strings that occur as arguments to invocations of formatting functions.
273287
*/
@@ -1046,39 +1060,63 @@ class FormatLiteral extends Literal {
10461060
or
10471061
this.getConversionChar(n).toLowerCase() = ["d", "i"] and
10481062
// e.g. -2^31 = "-2147483648"
1049-
exists(int sizeBits |
1050-
sizeBits =
1051-
min(int bits |
1052-
bits = this.getIntegralDisplayType(n).getSize() * 8
1053-
or
1054-
exists(IntegralType t |
1055-
t = this.getUse().getConversionArgument(n).getType().getUnderlyingType()
1056-
|
1057-
t.isSigned() and bits = t.getSize() * 8
1058-
)
1059-
) and
1060-
len = 1 + ((sizeBits - 1) / 10.0.log2()).ceil()
1061-
// this calculation is as %u (below) only we take out the sign bit (- 1) and allow a whole
1062-
// character for it to be expressed as '-'.
1063-
)
1063+
len =
1064+
min(float cand |
1065+
// The first case handles length sub-specifiers
1066+
// Subtract one in the exponent because one bit is for the sign.
1067+
// Add 1 to account for the possible sign in the output.
1068+
cand = 1 + lengthInBase10(2.pow(this.getIntegralDisplayType(n).getSize() * 8 - 1))
1069+
or
1070+
// The second case uses range analysis to deduce a length that's shorter than the length
1071+
// of the number -2^31.
1072+
exists(Expr arg, float lower, float upper |
1073+
arg = this.getUse().getConversionArgument(n) and
1074+
lower = lowerBound(arg.getFullyConverted()) and
1075+
upper = upperBound(arg.getFullyConverted())
1076+
|
1077+
cand =
1078+
max(int cand0 |
1079+
// Include the sign bit in the length if it can be negative
1080+
(
1081+
if lower < 0
1082+
then cand0 = 1 + lengthInBase10(lower.abs())
1083+
else cand0 = lengthInBase10(lower)
1084+
)
1085+
or
1086+
(
1087+
if upper < 0
1088+
then cand0 = 1 + lengthInBase10(upper.abs())
1089+
else cand0 = lengthInBase10(upper)
1090+
)
1091+
)
1092+
)
1093+
)
10641094
or
10651095
this.getConversionChar(n).toLowerCase() = "u" and
10661096
// e.g. 2^32 - 1 = "4294967295"
1067-
exists(int sizeBits |
1068-
sizeBits =
1069-
min(int bits |
1070-
bits = this.getIntegralDisplayType(n).getSize() * 8
1071-
or
1072-
exists(IntegralType t |
1073-
t = this.getUse().getConversionArgument(n).getType().getUnderlyingType()
1074-
|
1075-
t.isUnsigned() and bits = t.getSize() * 8
1076-
)
1077-
) and
1078-
len = (sizeBits / 10.0.log2()).ceil()
1079-
// convert the size from bits to decimal characters, and round up as you can't have
1080-
// fractional characters (10.0.log2() is the number of bits expressed per decimal character)
1081-
)
1097+
len =
1098+
min(float cand |
1099+
// The first case handles length sub-specifiers
1100+
cand = 2.pow(this.getIntegralDisplayType(n).getSize() * 8)
1101+
or
1102+
// The second case uses range analysis to deduce a length that's shorter than
1103+
// the length of the number 2^31 - 1.
1104+
exists(Expr arg, float lower |
1105+
arg = this.getUse().getConversionArgument(n) and
1106+
lower = lowerBound(arg.getFullyConverted())
1107+
|
1108+
cand =
1109+
max(float cand0 |
1110+
// If lower can be negative we use `(unsigned)-1` as the candidate value.
1111+
lower < 0 and
1112+
cand0 = 2.pow(any(IntType t | t.isUnsigned()).getSize() * 8)
1113+
or
1114+
cand0 = upperBound(arg.getFullyConverted())
1115+
)
1116+
)
1117+
|
1118+
lengthInBase10(cand)
1119+
)
10821120
or
10831121
this.getConversionChar(n).toLowerCase() = "x" and
10841122
// e.g. "12345678"

cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl.qll

+17-6
Original file line numberDiff line numberDiff line change
@@ -3740,13 +3740,14 @@ private module Subpaths {
37403740
*/
37413741
pragma[nomagic]
37423742
private predicate subpaths01(
3743-
PathNode arg, ParamNodeEx par, SummaryCtxSome sc, CallContext innercc, ReturnKindExt kind,
3743+
PathNodeImpl arg, ParamNodeEx par, SummaryCtxSome sc, CallContext innercc, ReturnKindExt kind,
37443744
NodeEx out, AccessPath apout
37453745
) {
37463746
exists(Configuration config |
37473747
pathThroughCallable(arg, out, _, pragma[only_bind_into](apout)) and
37483748
pathIntoCallable(arg, par, _, innercc, sc, _, config) and
3749-
paramFlowsThrough(kind, innercc, sc, pragma[only_bind_into](apout), _, unbindConf(config))
3749+
paramFlowsThrough(kind, innercc, sc, pragma[only_bind_into](apout), _, unbindConf(config)) and
3750+
not arg.isHidden()
37503751
)
37513752
}
37523753

@@ -3780,8 +3781,17 @@ private module Subpaths {
37803781
innercc = ret.getCallContext() and
37813782
sc = ret.getSummaryCtx() and
37823783
ret.getConfiguration() = unbindConf(getPathNodeConf(arg)) and
3783-
apout = ret.getAp() and
3784-
not ret.isHidden()
3784+
apout = ret.getAp()
3785+
)
3786+
}
3787+
3788+
private PathNodeImpl localStepToHidden(PathNodeImpl n) {
3789+
n.getASuccessorImpl() = result and
3790+
result.isHidden() and
3791+
exists(NodeEx n1, NodeEx n2 | n1 = n.getNodeEx() and n2 = result.getNodeEx() |
3792+
localFlowBigStep(n1, n2, _, _, _, _) or
3793+
store(n1, _, n2, _, _) or
3794+
read(n1, _, n2, _)
37853795
)
37863796
}
37873797

@@ -3790,11 +3800,12 @@ private module Subpaths {
37903800
* a subpath between `par` and `ret` with the connecting edges `arg -> par` and
37913801
* `ret -> out` is summarized as the edge `arg -> out`.
37923802
*/
3793-
predicate subpaths(PathNode arg, PathNodeImpl par, PathNodeMid ret, PathNodeMid out) {
3803+
predicate subpaths(PathNode arg, PathNodeImpl par, PathNodeImpl ret, PathNodeMid out) {
37943804
exists(ParamNodeEx p, NodeEx o, AccessPath apout |
37953805
pragma[only_bind_into](arg).getASuccessor() = par and
37963806
pragma[only_bind_into](arg).getASuccessor() = out and
3797-
subpaths03(arg, p, ret, o, apout) and
3807+
subpaths03(arg, p, localStepToHidden*(ret), o, apout) and
3808+
not ret.isHidden() and
37983809
par.getNodeEx() = p and
37993810
out.getNodeEx() = o and
38003811
out.getAp() = apout

cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl2.qll

+17-6
Original file line numberDiff line numberDiff line change
@@ -3740,13 +3740,14 @@ private module Subpaths {
37403740
*/
37413741
pragma[nomagic]
37423742
private predicate subpaths01(
3743-
PathNode arg, ParamNodeEx par, SummaryCtxSome sc, CallContext innercc, ReturnKindExt kind,
3743+
PathNodeImpl arg, ParamNodeEx par, SummaryCtxSome sc, CallContext innercc, ReturnKindExt kind,
37443744
NodeEx out, AccessPath apout
37453745
) {
37463746
exists(Configuration config |
37473747
pathThroughCallable(arg, out, _, pragma[only_bind_into](apout)) and
37483748
pathIntoCallable(arg, par, _, innercc, sc, _, config) and
3749-
paramFlowsThrough(kind, innercc, sc, pragma[only_bind_into](apout), _, unbindConf(config))
3749+
paramFlowsThrough(kind, innercc, sc, pragma[only_bind_into](apout), _, unbindConf(config)) and
3750+
not arg.isHidden()
37503751
)
37513752
}
37523753

@@ -3780,8 +3781,17 @@ private module Subpaths {
37803781
innercc = ret.getCallContext() and
37813782
sc = ret.getSummaryCtx() and
37823783
ret.getConfiguration() = unbindConf(getPathNodeConf(arg)) and
3783-
apout = ret.getAp() and
3784-
not ret.isHidden()
3784+
apout = ret.getAp()
3785+
)
3786+
}
3787+
3788+
private PathNodeImpl localStepToHidden(PathNodeImpl n) {
3789+
n.getASuccessorImpl() = result and
3790+
result.isHidden() and
3791+
exists(NodeEx n1, NodeEx n2 | n1 = n.getNodeEx() and n2 = result.getNodeEx() |
3792+
localFlowBigStep(n1, n2, _, _, _, _) or
3793+
store(n1, _, n2, _, _) or
3794+
read(n1, _, n2, _)
37853795
)
37863796
}
37873797

@@ -3790,11 +3800,12 @@ private module Subpaths {
37903800
* a subpath between `par` and `ret` with the connecting edges `arg -> par` and
37913801
* `ret -> out` is summarized as the edge `arg -> out`.
37923802
*/
3793-
predicate subpaths(PathNode arg, PathNodeImpl par, PathNodeMid ret, PathNodeMid out) {
3803+
predicate subpaths(PathNode arg, PathNodeImpl par, PathNodeImpl ret, PathNodeMid out) {
37943804
exists(ParamNodeEx p, NodeEx o, AccessPath apout |
37953805
pragma[only_bind_into](arg).getASuccessor() = par and
37963806
pragma[only_bind_into](arg).getASuccessor() = out and
3797-
subpaths03(arg, p, ret, o, apout) and
3807+
subpaths03(arg, p, localStepToHidden*(ret), o, apout) and
3808+
not ret.isHidden() and
37983809
par.getNodeEx() = p and
37993810
out.getNodeEx() = o and
38003811
out.getAp() = apout

cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl3.qll

+17-6
Original file line numberDiff line numberDiff line change
@@ -3740,13 +3740,14 @@ private module Subpaths {
37403740
*/
37413741
pragma[nomagic]
37423742
private predicate subpaths01(
3743-
PathNode arg, ParamNodeEx par, SummaryCtxSome sc, CallContext innercc, ReturnKindExt kind,
3743+
PathNodeImpl arg, ParamNodeEx par, SummaryCtxSome sc, CallContext innercc, ReturnKindExt kind,
37443744
NodeEx out, AccessPath apout
37453745
) {
37463746
exists(Configuration config |
37473747
pathThroughCallable(arg, out, _, pragma[only_bind_into](apout)) and
37483748
pathIntoCallable(arg, par, _, innercc, sc, _, config) and
3749-
paramFlowsThrough(kind, innercc, sc, pragma[only_bind_into](apout), _, unbindConf(config))
3749+
paramFlowsThrough(kind, innercc, sc, pragma[only_bind_into](apout), _, unbindConf(config)) and
3750+
not arg.isHidden()
37503751
)
37513752
}
37523753

@@ -3780,8 +3781,17 @@ private module Subpaths {
37803781
innercc = ret.getCallContext() and
37813782
sc = ret.getSummaryCtx() and
37823783
ret.getConfiguration() = unbindConf(getPathNodeConf(arg)) and
3783-
apout = ret.getAp() and
3784-
not ret.isHidden()
3784+
apout = ret.getAp()
3785+
)
3786+
}
3787+
3788+
private PathNodeImpl localStepToHidden(PathNodeImpl n) {
3789+
n.getASuccessorImpl() = result and
3790+
result.isHidden() and
3791+
exists(NodeEx n1, NodeEx n2 | n1 = n.getNodeEx() and n2 = result.getNodeEx() |
3792+
localFlowBigStep(n1, n2, _, _, _, _) or
3793+
store(n1, _, n2, _, _) or
3794+
read(n1, _, n2, _)
37853795
)
37863796
}
37873797

@@ -3790,11 +3800,12 @@ private module Subpaths {
37903800
* a subpath between `par` and `ret` with the connecting edges `arg -> par` and
37913801
* `ret -> out` is summarized as the edge `arg -> out`.
37923802
*/
3793-
predicate subpaths(PathNode arg, PathNodeImpl par, PathNodeMid ret, PathNodeMid out) {
3803+
predicate subpaths(PathNode arg, PathNodeImpl par, PathNodeImpl ret, PathNodeMid out) {
37943804
exists(ParamNodeEx p, NodeEx o, AccessPath apout |
37953805
pragma[only_bind_into](arg).getASuccessor() = par and
37963806
pragma[only_bind_into](arg).getASuccessor() = out and
3797-
subpaths03(arg, p, ret, o, apout) and
3807+
subpaths03(arg, p, localStepToHidden*(ret), o, apout) and
3808+
not ret.isHidden() and
37983809
par.getNodeEx() = p and
37993810
out.getNodeEx() = o and
38003811
out.getAp() = apout

0 commit comments

Comments
 (0)