Skip to content

Commit 09ec313

Browse files
Merge branch 'github:main' into main-1
2 parents 4024e83 + e6884cf commit 09ec313

File tree

45 files changed

+575
-54
lines changed

Some content is hidden

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

45 files changed

+575
-54
lines changed

cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/SsaInternalsCommon.qll

+25-9
Original file line numberDiff line numberDiff line change
@@ -630,10 +630,18 @@ private module Cached {
630630
Operand operand, int indirectionIndex, Operand operandRepr, int indirectionIndexRepr
631631
) {
632632
indirectionIndex = [1 .. countIndirectionsForCppType(getLanguageType(operand))] and
633-
exists(Instruction load |
634-
isDereference(load, operand, false) and
635-
operandRepr = unique( | | getAUse(load)) and
636-
indirectionIndexRepr = indirectionIndex - 1
633+
(
634+
exists(Instruction load |
635+
isDereference(load, operand, false) and
636+
operandRepr = unique( | | getAUse(load)) and
637+
indirectionIndexRepr = indirectionIndex - 1
638+
)
639+
or
640+
exists(CopyValueInstruction copy |
641+
copy.getSourceValueOperand() = operand and
642+
operandRepr = unique( | | getAUse(copy)) and
643+
indirectionIndexRepr = indirectionIndex
644+
)
637645
)
638646
}
639647

@@ -649,11 +657,19 @@ private module Cached {
649657
Instruction instr, int indirectionIndex, Instruction instrRepr, int indirectionIndexRepr
650658
) {
651659
indirectionIndex = [1 .. countIndirectionsForCppType(getResultLanguageType(instr))] and
652-
exists(Instruction load, Operand address |
653-
address = unique( | | getAUse(instr)) and
654-
isDereference(load, address, false) and
655-
instrRepr = load and
656-
indirectionIndexRepr = indirectionIndex - 1
660+
(
661+
exists(Instruction load, Operand address |
662+
address = unique( | | getAUse(instr)) and
663+
isDereference(load, address, false) and
664+
instrRepr = load and
665+
indirectionIndexRepr = indirectionIndex - 1
666+
)
667+
or
668+
exists(CopyValueInstruction copy |
669+
copy.getSourceValueOperand() = unique( | | getAUse(instr)) and
670+
instrRepr = copy and
671+
indirectionIndexRepr = indirectionIndex
672+
)
657673
)
658674
}
659675

cpp/ql/test/library-tests/dataflow/dataflow-tests/localFlow-ir.expected

-8
Original file line numberDiff line numberDiff line change
@@ -53,11 +53,9 @@
5353
| example.c:26:18:26:24 | *& ... | example.c:26:2:26:7 | *coords |
5454
| example.c:26:18:26:24 | getX output argument | example.c:26:2:26:7 | *coords |
5555
| example.c:26:18:26:24 | pointer to getX output argument | example.c:26:2:26:7 | coords |
56-
| example.c:26:19:26:24 | *coords | example.c:26:18:26:24 | *& ... |
5756
| example.c:26:19:26:24 | coords | example.c:26:18:26:24 | & ... |
5857
| example.c:28:22:28:25 | & ... | example.c:28:14:28:25 | & ... |
5958
| example.c:28:22:28:25 | *& ... | example.c:28:14:28:25 | *& ... |
60-
| example.c:28:23:28:25 | *pos | example.c:28:22:28:25 | *& ... |
6159
| example.c:28:23:28:25 | pos | example.c:28:22:28:25 | & ... |
6260
| test.cpp:6:12:6:17 | call to source | test.cpp:6:12:6:17 | call to source |
6361
| test.cpp:6:12:6:17 | call to source | test.cpp:7:8:7:9 | t1 |
@@ -134,7 +132,6 @@
134132
| test.cpp:384:10:384:13 | *& ... | test.cpp:384:10:384:13 | *& ... |
135133
| test.cpp:384:10:384:13 | memcpy output argument | test.cpp:385:8:385:10 | tmp |
136134
| test.cpp:384:10:384:13 | pointer to memcpy output argument | test.cpp:385:8:385:10 | tmp |
137-
| test.cpp:384:11:384:13 | *tmp | test.cpp:384:10:384:13 | *& ... |
138135
| test.cpp:384:11:384:13 | tmp | test.cpp:384:10:384:13 | & ... |
139136
| test.cpp:384:16:384:23 | & ... | test.cpp:384:16:384:23 | & ... |
140137
| test.cpp:384:16:384:23 | *& ... | test.cpp:384:3:384:8 | **call to memcpy |
@@ -143,7 +140,6 @@
143140
| test.cpp:384:16:384:23 | *& ... | test.cpp:384:16:384:23 | *& ... |
144141
| test.cpp:384:16:384:23 | **& ... | test.cpp:384:3:384:8 | **call to memcpy |
145142
| test.cpp:384:16:384:23 | **& ... | test.cpp:384:10:384:13 | memcpy output argument |
146-
| test.cpp:384:17:384:23 | *source1 | test.cpp:384:16:384:23 | *& ... |
147143
| test.cpp:384:17:384:23 | source1 | test.cpp:384:16:384:23 | & ... |
148144
| test.cpp:388:53:388:59 | source1 | test.cpp:391:16:391:23 | *& ... |
149145
| test.cpp:388:66:388:66 | b | test.cpp:393:7:393:7 | b |
@@ -153,15 +149,13 @@
153149
| test.cpp:390:18:390:21 | & ... | test.cpp:391:10:391:13 | & ... |
154150
| test.cpp:390:18:390:21 | *& ... | test.cpp:390:18:390:21 | *& ... |
155151
| test.cpp:390:18:390:21 | *& ... | test.cpp:391:10:391:13 | *& ... |
156-
| test.cpp:390:19:390:21 | *tmp | test.cpp:390:18:390:21 | *& ... |
157152
| test.cpp:390:19:390:21 | tmp | test.cpp:390:18:390:21 | & ... |
158153
| test.cpp:391:10:391:13 | & ... | test.cpp:391:3:391:8 | call to memcpy |
159154
| test.cpp:391:10:391:13 | & ... | test.cpp:391:10:391:13 | & ... |
160155
| test.cpp:391:10:391:13 | & ... | test.cpp:392:8:392:10 | tmp |
161156
| test.cpp:391:10:391:13 | *& ... | test.cpp:391:10:391:13 | *& ... |
162157
| test.cpp:391:10:391:13 | memcpy output argument | test.cpp:392:8:392:10 | tmp |
163158
| test.cpp:391:10:391:13 | pointer to memcpy output argument | test.cpp:392:8:392:10 | tmp |
164-
| test.cpp:391:11:391:13 | *tmp | test.cpp:391:10:391:13 | *& ... |
165159
| test.cpp:391:11:391:13 | tmp | test.cpp:391:10:391:13 | & ... |
166160
| test.cpp:391:16:391:23 | & ... | test.cpp:391:16:391:23 | & ... |
167161
| test.cpp:391:16:391:23 | *& ... | test.cpp:391:3:391:8 | **call to memcpy |
@@ -170,7 +164,6 @@
170164
| test.cpp:391:16:391:23 | *& ... | test.cpp:391:16:391:23 | *& ... |
171165
| test.cpp:391:16:391:23 | **& ... | test.cpp:391:3:391:8 | **call to memcpy |
172166
| test.cpp:391:16:391:23 | **& ... | test.cpp:391:10:391:13 | memcpy output argument |
173-
| test.cpp:391:17:391:23 | *source1 | test.cpp:391:16:391:23 | *& ... |
174167
| test.cpp:391:17:391:23 | source1 | test.cpp:391:16:391:23 | & ... |
175168
| test.cpp:392:8:392:10 | tmp | test.cpp:394:10:394:12 | tmp |
176169
| test.cpp:392:8:392:10 | tmp | test.cpp:394:10:394:12 | tmp |
@@ -209,5 +202,4 @@
209202
| test.cpp:1087:3:1087:3 | a [post update] | test.cpp:1088:8:1088:9 | & ... |
210203
| test.cpp:1087:15:1087:21 | 0 | test.cpp:1087:3:1087:21 | ... = ... |
211204
| test.cpp:1087:15:1087:21 | *0 | test.cpp:1087:3:1087:21 | *... = ... |
212-
| test.cpp:1088:9:1088:9 | *a | test.cpp:1088:8:1088:9 | *& ... |
213205
| test.cpp:1088:9:1088:9 | a | test.cpp:1088:8:1088:9 | & ... |

csharp/ql/lib/semmle/code/csharp/controlflow/internal/Completion.qll

+2
Original file line numberDiff line numberDiff line change
@@ -293,6 +293,8 @@ private predicate isMatchingConstant(PatternExpr pe, boolean value) {
293293
value = true
294294
or
295295
exists(Type t, Type strippedType |
296+
not t instanceof UnknownType and
297+
not strippedType instanceof UnknownType and
296298
typePatternMustHaveMatchingCompletion(pe, t, strippedType) and
297299
not typePatternCommonSubType(t, strippedType) and
298300
value = false
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
---
2+
category: minorAnalysis
3+
---
4+
* Increase query precision for `cs/useless-assignment-to-local` and `cs/constant-condition` when *unknown* types are involved (mostly relevant for `build-mode: none` databases).

csharp/ql/src/codeql-suites/csharp-ccr.qls

+1
Original file line numberDiff line numberDiff line change
@@ -7,3 +7,4 @@
77
- cs/reference-equality-on-valuetypes
88
- cs/self-assignment
99
- cs/inefficient-containskey
10+
- cs/call-to-object-tostring
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
using System;
2+
3+
partial class C1
4+
{
5+
public C2 Prop { get; set; }
6+
}
7+
8+
class C2 { }
9+
10+
class ConstantMatching
11+
{
12+
void M1()
13+
{
14+
var c1 = new C1();
15+
if (c1.Prop is int) // $ Alert
16+
{
17+
}
18+
19+
// Should not be considered a constant condition as
20+
// we don't know anything about D.
21+
var d = new D();
22+
if (d.Prop is C2)
23+
{
24+
}
25+
}
26+
}
27+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
| ConstantCondition.cs:15:13:15:26 | ... is ... | Condition always evaluates to 'false'. |
2+
| ConstantCondition.cs:15:24:15:26 | access to type Int32 | Pattern never matches. |
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
query: Bad Practices/Control-Flow/ConstantCondition.ql
2+
postprocess: utils/test/InlineExpectationsTestQuery.ql
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
semmle-extractor-options: --standalone

docs/codeql/reusables/supported-versions-compilers.rst

+1-1
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
Python [8]_,"2.7, 3.5, 3.6, 3.7, 3.8, 3.9, 3.10, 3.11, 3.12, 3.13",Not applicable,``.py``
2626
Ruby [9]_,"up to 3.3",Not applicable,"``.rb``, ``.erb``, ``.gemspec``, ``Gemfile``"
2727
Swift [10]_,"Swift 5.4-6.0","Swift compiler","``.swift``"
28-
TypeScript [11]_,"2.6-5.7",Standard TypeScript compiler,"``.ts``, ``.tsx``, ``.mts``, ``.cts``"
28+
TypeScript [11]_,"2.6-5.8",Standard TypeScript compiler,"``.ts``, ``.tsx``, ``.mts``, ``.cts``"
2929

3030
.. container:: footnote-group
3131

javascript/extractor/lib/typescript/package-lock.json

+4-4
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

javascript/extractor/lib/typescript/package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
"name": "typescript-parser-wrapper",
33
"private": true,
44
"dependencies": {
5-
"typescript": "^5.7.2"
5+
"typescript": "^5.8.2"
66
},
77
"scripts": {
88
"build": "tsc --project tsconfig.json",
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
---
2+
category: majorAnalysis
3+
---
4+
* Added support for TypeScript 5.8.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
---
2+
category: minorAnalysis
3+
---
4+
* Added support for the `react-relay` library.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
extensions:
2+
- addsTo:
3+
pack: codeql/javascript-all
4+
extensible: sourceModel
5+
data:
6+
- ["react-relay", "Member[useFragment].ReturnValue", "response"]
7+
- ["react-relay", "Member[useLazyLoadQuery].ReturnValue", "response"]
8+
- ["react-relay", "Member[usePreloadedQuery].ReturnValue", "response"]
9+
- ["react-relay", "Member[useClientQuery].ReturnValue", "response"]
10+
- ["react-relay", "Member[useRefetchableFragment].ReturnValue.Member[0]", "response"]
11+
- ["react-relay", "Member[usePaginationFragment].ReturnValue.Member[data]", "response"]
12+
- ["react-relay", "Member[useMutation].ReturnValue.Member[0].Argument[0].Member[onCompleted].Parameter[0]", "response"]
13+
- ["react-relay", "Member[useSubscription].Argument[0].Member[onNext].Parameter[0]", "response"]
14+
- ["react-relay", "Member[fetchQuery].ReturnValue.Member[subscribe].Argument[0].Member[next].Parameter[0]", "response"]
15+
- ["relay-runtime", "Member[readFragment].ReturnValue", "response"]

javascript/ql/lib/semmle/javascript/MembershipCandidates.qll

+6-11
Original file line numberDiff line numberDiff line change
@@ -140,22 +140,17 @@ module MembershipCandidate {
140140
EnumerationRegExp() {
141141
this.isRootTerm() and
142142
RegExp::isFullyAnchoredTerm(this) and
143-
exists(RegExpTerm child | this.getAChild*() = child |
144-
child instanceof RegExpSequence or
145-
child instanceof RegExpCaret or
146-
child instanceof RegExpDollar or
147-
child instanceof RegExpConstant or
148-
child instanceof RegExpAlt or
149-
child instanceof RegExpGroup
150-
) and
151-
// exclude "length matches" that match every string
152-
not this.getAChild*() instanceof RegExpDot
143+
not exists(RegExpTerm child | child.getRootTerm() = this |
144+
child instanceof RegExpDot or
145+
child instanceof RegExpCharacterClass or
146+
child instanceof RegExpUnicodePropertyEscape
147+
)
153148
}
154149

155150
/**
156151
* Gets a string matched by this regular expression.
157152
*/
158-
string getAMember() { result = this.getAChild*().getAMatchedString() }
153+
string getAMember() { result = any(RegExpTerm t | t.getRootTerm() = this).getAMatchedString() }
159154
}
160155

161156
/**

javascript/ql/lib/semmle/javascript/Routing.qll

+18-10
Original file line numberDiff line numberDiff line change
@@ -188,27 +188,35 @@ module Routing {
188188
)
189189
}
190190

191-
/**
192-
* Gets the path prefix needed to reach this node from the given ancestor, that is, the concatenation
193-
* of all relative paths between this node and the ancestor.
194-
*
195-
* To restrict the size of the predicate, this is only available for the ancestors that are "fork" nodes,
196-
* that is, a node that has siblings (i.e. multiple children).
197-
*/
198-
private string getPathFromFork(Node fork) {
191+
private string getPathFromForkInternal(Node fork) {
199192
this.isFork() and
200193
this = fork and
201194
result = ""
202195
or
203196
exists(Node parent | parent = this.getParent() |
204197
not exists(parent.getRelativePath()) and
205-
result = parent.getPathFromFork(fork)
198+
result = parent.getPathFromForkInternal(fork)
206199
or
207-
result = parent.getPathFromFork(fork) + parent.getRelativePath() and
200+
result = parent.getPathFromForkInternal(fork) + parent.getRelativePath() and
208201
result.length() < 100
209202
)
210203
}
211204

205+
/**
206+
* Gets the path prefix needed to reach this node from the given ancestor, that is, the concatenation
207+
* of all relative paths between this node and the ancestor.
208+
*
209+
* To restrict the size of the predicate, this is only available for the ancestors that are "fork" nodes,
210+
* that is, a node that has siblings (i.e. multiple children).
211+
* And only a single (shortest) path is returned, even if there are multiple paths
212+
* leading to this node.
213+
*/
214+
pragma[nomagic]
215+
private string getPathFromFork(Node fork) {
216+
result =
217+
min(string res | res = this.getPathFromForkInternal(fork) | res order by res.length(), res)
218+
}
219+
212220
/**
213221
* Gets an HTTP method required to reach this node from the given ancestor, or `*` if any method
214222
* can be used.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
---
2+
category: fix
3+
---
4+
* Fixed a bug that would in rare cases cause some regexp-based checks
5+
to be seen as generic taint sanitisers, even though the underlying regexp
6+
is not restrictive enough. The regexps are now analysed more precisely,
7+
and unrestrictive regexp checks will no longer block taint flow.

javascript/ql/src/meta/alerts/TaintedNodes.ql

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
* via default taint-tracking steps.
55
* @kind problem
66
* @problem.severity recommendation
7-
* @tags meta
7+
* @tags meta-expensive
88
* @id js/meta/alerts/tainted-nodes
99
* @precision very-low
1010
*/

javascript/ql/test/library-tests/TaintTracking/BasicTaintTracking.expected

+1
Original file line numberDiff line numberDiff line change
@@ -238,6 +238,7 @@ flow
238238
| promise.js:18:22:18:29 | source() | promise.js:24:10:24:10 | e |
239239
| promise.js:33:21:33:28 | source() | promise.js:38:10:38:10 | e |
240240
| promise.js:43:20:43:27 | source() | promise.js:43:8:43:28 | Promise ... urce()) |
241+
| regexp-sanitiser.js:2:19:2:26 | source() | regexp-sanitiser.js:4:14:4:18 | taint |
241242
| rxjs.js:3:1:3:8 | source() | rxjs.js:10:14:10:17 | data |
242243
| rxjs.js:13:1:13:8 | source() | rxjs.js:17:23:17:23 | x |
243244
| rxjs.js:13:1:13:8 | source() | rxjs.js:18:23:18:23 | x |

javascript/ql/test/library-tests/TaintTracking/DataFlowTracking.expected

+1
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,7 @@ flow
161161
| partialCalls.js:4:17:4:24 | source() | partialCalls.js:30:14:30:20 | x.value |
162162
| partialCalls.js:4:17:4:24 | source() | partialCalls.js:41:10:41:18 | id(taint) |
163163
| partialCalls.js:4:17:4:24 | source() | partialCalls.js:51:14:51:14 | x |
164+
| regexp-sanitiser.js:2:19:2:26 | source() | regexp-sanitiser.js:4:14:4:18 | taint |
164165
| sanitizer-function.js:12:17:12:24 | source() | sanitizer-function.js:14:10:14:14 | taint |
165166
| sanitizer-function.js:12:17:12:24 | source() | sanitizer-function.js:17:14:17:18 | taint |
166167
| sanitizer-function.js:12:17:12:24 | source() | sanitizer-function.js:21:14:21:18 | taint |
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
function foo() {
2+
const taint = source();
3+
if (/^asd[\s\S]*$/.test(taint)) {
4+
sink(taint); // NOT OK
5+
}
6+
}

0 commit comments

Comments
 (0)