Skip to content

Commit a60c52b

Browse files
authored
Merge branch 'main' into python/captured-variables-basic
2 parents 8b7b582 + f50817e commit a60c52b

File tree

70 files changed

+1111
-840
lines changed

Some content is hidden

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

70 files changed

+1111
-840
lines changed

config/identical-files.json

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -454,10 +454,6 @@
454454
"ruby/ql/lib/codeql/ruby/security/internal/SensitiveDataHeuristics.qll",
455455
"swift/ql/lib/codeql/swift/security/internal/SensitiveDataHeuristics.qll"
456456
],
457-
"SummaryTypeTracker": [
458-
"python/ql/lib/semmle/python/dataflow/new/internal/SummaryTypeTracker.qll",
459-
"ruby/ql/lib/codeql/ruby/typetracking/internal/SummaryTypeTracker.qll"
460-
],
461457
"IncompleteUrlSubstringSanitization": [
462458
"javascript/ql/src/Security/CWE-020/IncompleteUrlSubstringSanitization.qll",
463459
"ruby/ql/src/queries/security/cwe-020/IncompleteUrlSubstringSanitization.qll"

cpp/ql/lib/semmle/code/cpp/Function.qll

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -328,6 +328,7 @@ class Function extends Declaration, ControlFlowNode, AccessHolder, @function {
328328
MetricFunction getMetrics() { result = this }
329329

330330
/** Holds if this function calls the function `f`. */
331+
pragma[nomagic]
331332
predicate calls(Function f) { this.calls(f, _) }
332333

333334
/**
@@ -338,10 +339,6 @@ class Function extends Declaration, ControlFlowNode, AccessHolder, @function {
338339
exists(FunctionCall call |
339340
call.getEnclosingFunction() = this and call.getTarget() = f and call = l
340341
)
341-
or
342-
exists(DestructorCall call |
343-
call.getEnclosingFunction() = this and call.getTarget() = f and call = l
344-
)
345342
}
346343

347344
/** Holds if this function accesses a function or variable or enumerator `a`. */

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -997,7 +997,8 @@ private Type getTypeImpl0(Type t, int indirectionIndex) {
997997
*
998998
* If `indirectionIndex` cannot be stripped off `t`, an `UnknownType` is returned.
999999
*/
1000-
bindingset[indirectionIndex]
1000+
bindingset[t, indirectionIndex]
1001+
pragma[inline_late]
10011002
Type getTypeImpl(Type t, int indirectionIndex) {
10021003
result = getTypeImpl0(t, indirectionIndex)
10031004
or

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

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -418,6 +418,11 @@ class BaseCallVariable extends AbstractBaseSourceVariable, TBaseCallVariable {
418418
}
419419

420420
private module IsModifiableAtImpl {
421+
pragma[nomagic]
422+
private predicate isUnderlyingIndirectionType(Type t) {
423+
t = any(Indirection ind).getUnderlyingType()
424+
}
425+
421426
/**
422427
* Holds if the `indirectionIndex`'th dereference of a value of type
423428
* `cppType` is a type that can be modified (either by modifying the value
@@ -445,10 +450,9 @@ private module IsModifiableAtImpl {
445450
bindingset[cppType, indirectionIndex]
446451
pragma[inline_late]
447452
private predicate impl(CppType cppType, int indirectionIndex) {
448-
exists(Type pointerType, Type base, Type t |
449-
pointerType = t.getUnderlyingType() and
450-
pointerType = any(Indirection ind).getUnderlyingType() and
451-
cppType.hasType(t, _) and
453+
exists(Type pointerType, Type base |
454+
isUnderlyingIndirectionType(pointerType) and
455+
cppType.hasUnderlyingType(pointerType, _) and
452456
base = getTypeImpl(pointerType, indirectionIndex)
453457
|
454458
// The value cannot be modified if it has a const specifier,

cpp/ql/lib/semmle/code/cpp/ir/internal/CppType.qll

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -227,7 +227,7 @@ class CppType extends TCppType {
227227
predicate hasType(Type type, boolean isGLValue) { none() }
228228

229229
/**
230-
* Holds if this type represents the C++ type `type`. If `isGLValue` is `true`, then this type
230+
* Holds if this type represents the C++ unspecified type `type`. If `isGLValue` is `true`, then this type
231231
* represents a glvalue of type `type`. Otherwise, it represents a prvalue of type `type`.
232232
*/
233233
final predicate hasUnspecifiedType(Type type, boolean isGLValue) {
@@ -236,6 +236,18 @@ class CppType extends TCppType {
236236
type = specifiedType.getUnspecifiedType()
237237
)
238238
}
239+
240+
/**
241+
* Holds if this type represents the C++ type `type` (after resolving
242+
* typedefs). If `isGLValue` is `true`, then this type represents a glvalue
243+
* of type `type`. Otherwise, it represents a prvalue of type `type`.
244+
*/
245+
final predicate hasUnderlyingType(Type type, boolean isGLValue) {
246+
exists(Type typedefType |
247+
this.hasType(typedefType, isGLValue) and
248+
type = typedefType.getUnderlyingType()
249+
)
250+
}
239251
}
240252

241253
/**

cpp/ql/lib/semmle/code/cpp/models/interfaces/FormattingFunction.qll

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,9 @@
99
import semmle.code.cpp.models.interfaces.ArrayFunction
1010
import semmle.code.cpp.models.interfaces.Taint
1111

12+
pragma[nomagic]
1213
private Type stripTopLevelSpecifiersOnly(Type t) {
13-
result = stripTopLevelSpecifiersOnly(t.(SpecifiedType).getBaseType())
14+
result = stripTopLevelSpecifiersOnly(pragma[only_bind_out](t.(SpecifiedType).getBaseType()))
1415
or
1516
result = t and
1617
not t instanceof SpecifiedType

cpp/ql/src/Critical/FlowAfterFree.qll

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,8 @@ module FlowFromFree<isSinkSig/2 isASink, isExcludedSig/2 isExcluded> {
8787
|
8888
e = any(StoreInstruction store).getDestinationAddress().getUnconvertedResultExpression()
8989
)
90+
or
91+
n.asExpr() instanceof ArrayExpr
9092
}
9193
}
9294

cpp/ql/src/Critical/UseAfterFree.ql

Lines changed: 26 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -101,35 +101,43 @@ module ParameterSinks {
101101
)
102102
}
103103

104-
private CallInstruction getAnAlwaysReachedCallInstruction(IRFunction f) {
105-
result.getBlock().postDominates(f.getEntryBlock())
104+
private CallInstruction getAnAlwaysReachedCallInstruction() {
105+
exists(IRFunction f | result.getBlock().postDominates(f.getEntryBlock()))
106106
}
107107

108108
pragma[nomagic]
109-
predicate callHasTargetAndArgument(Function f, int i, CallInstruction call, Instruction argument) {
110-
call.getStaticCallTarget() = f and
111-
call.getArgument(i) = argument
109+
private predicate callHasTargetAndArgument(Function f, int i, Instruction argument) {
110+
exists(CallInstruction call |
111+
call.getStaticCallTarget() = f and
112+
call.getArgument(i) = argument and
113+
call = getAnAlwaysReachedCallInstruction()
114+
)
115+
}
116+
117+
pragma[nomagic]
118+
private predicate initializeParameterInFunction(Function f, int i) {
119+
exists(InitializeParameterInstruction init |
120+
pragma[only_bind_out](init.getEnclosingFunction()) = f and
121+
init.hasIndex(i) and
122+
init = getAnAlwaysDereferencedParameter()
123+
)
112124
}
113125

114126
pragma[nomagic]
115-
predicate initializeParameterInFunction(Function f, int i, InitializeParameterInstruction init) {
116-
pragma[only_bind_out](init.getEnclosingFunction()) = f and
117-
init.hasIndex(i)
127+
private predicate alwaysDereferencedArgumentHasValueNumber(ValueNumber vn) {
128+
exists(int i, Function f, Instruction argument |
129+
callHasTargetAndArgument(f, i, argument) and
130+
initializeParameterInFunction(pragma[only_bind_into](f), pragma[only_bind_into](i)) and
131+
vn.getAnInstruction() = argument
132+
)
118133
}
119134

120135
InitializeParameterInstruction getAnAlwaysDereferencedParameter() {
121136
result = getAnAlwaysDereferencedParameter0()
122137
or
123-
exists(
124-
CallInstruction call, int i, InitializeParameterInstruction p, Instruction argument,
125-
Function f
126-
|
127-
callHasTargetAndArgument(f, i, call, argument) and
128-
initializeParameterInFunction(f, i, p) and
129-
p = getAnAlwaysDereferencedParameter() and
130-
result =
131-
pragma[only_bind_out](pragma[only_bind_into](valueNumber(argument)).getAnInstruction()) and
132-
call = getAnAlwaysReachedCallInstruction(_)
138+
exists(ValueNumber vn |
139+
alwaysDereferencedArgumentHasValueNumber(vn) and
140+
vn.getAnInstruction() = result
133141
)
134142
}
135143
}

cpp/ql/src/jsf/4.10 Classes/AV Rule 79.ql

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -126,13 +126,13 @@ class Resource extends MemberVariable {
126126
}
127127

128128
private predicate calledFromDestructor(Function f) {
129-
f instanceof Destructor and f.getDeclaringType() = this.getDeclaringType()
129+
pragma[only_bind_into](f) instanceof Destructor and
130+
f.getDeclaringType() = this.getDeclaringType()
130131
or
131-
exists(Function mid, FunctionCall fc |
132+
exists(Function mid |
132133
this.calledFromDestructor(mid) and
133-
fc.getEnclosingFunction() = mid and
134-
fc.getTarget() = f and
135-
f.getDeclaringType() = this.getDeclaringType()
134+
mid.calls(f) and
135+
pragma[only_bind_out](f.getDeclaringType()) = pragma[only_bind_out](this.getDeclaringType())
136136
)
137137
}
138138

cpp/ql/src/jsf/4.16 Initialization/AV Rule 145.ql

Lines changed: 30 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -32,18 +32,41 @@ predicate hasReferenceInitializer(EnumConstant c) {
3232
)
3333
}
3434

35+
/**
36+
* Gets the `rnk`'th (1-based) enumeration constant in `e` that does not have a
37+
* reference initializer (i.e., an initializer that refers to an enumeration
38+
* constant from the same enumeration).
39+
*/
40+
EnumConstant getNonReferenceInitializedEnumConstantByRank(Enum e, int rnk) {
41+
result =
42+
rank[rnk](EnumConstant cand, int pos, string filepath, int startline, int startcolumn |
43+
e.getEnumConstant(pos) = cand and
44+
not hasReferenceInitializer(cand) and
45+
cand.getLocation().hasLocationInfo(filepath, startline, startcolumn, _, _)
46+
|
47+
cand order by pos, filepath, startline, startcolumn
48+
)
49+
}
50+
51+
/**
52+
* Holds if `ec` is not the last enumeration constant in `e` that has a non-
53+
* reference initializer.
54+
*/
55+
predicate hasNextWithoutReferenceInitializer(Enum e, EnumConstant ec) {
56+
exists(int rnk |
57+
ec = getNonReferenceInitializedEnumConstantByRank(e, rnk) and
58+
exists(getNonReferenceInitializedEnumConstantByRank(e, rnk + 1))
59+
)
60+
}
61+
3562
// There exists another constant whose value is implicit, but it's
3663
// not the last one: the last value is okay to use to get the highest
3764
// enum value automatically. It can be followed by aliases though.
3865
predicate enumThatHasConstantWithImplicitValue(Enum e) {
39-
exists(EnumConstant ec, int pos |
40-
ec = e.getEnumConstant(pos) and
66+
exists(EnumConstant ec |
67+
ec = e.getAnEnumConstant() and
4168
not hasInitializer(ec) and
42-
exists(EnumConstant ec2, int pos2 |
43-
ec2 = e.getEnumConstant(pos2) and
44-
pos2 > pos and
45-
not hasReferenceInitializer(ec2)
46-
)
69+
hasNextWithoutReferenceInitializer(e, ec)
4770
)
4871
}
4972

0 commit comments

Comments
 (0)