Skip to content

Commit ac517b7

Browse files
committed
Merge branch 'master' into rdmarsh/cpp/malloc-alias-locations
2 parents 95a762c + 0da554c commit ac517b7

File tree

190 files changed

+2000
-1071
lines changed

Some content is hidden

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

190 files changed

+2000
-1071
lines changed

change-notes/1.24/analysis-javascript.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@
4343
| Cross-site scripting through exception (`js/xss-through-exception`) | security, external/cwe/cwe-079, external/cwe/cwe-116 | Highlights potential XSS vulnerabilities where an exception is written to the DOM. Results are not shown on LGTM by default. |
4444
| Regular expression always matches (`js/regex/always-matches`) | correctness, regular-expressions | Highlights regular expression checks that trivially succeed by matching an empty substring. Results are shown on LGTM by default. |
4545
| Missing await (`js/missing-await`) | correctness | Highlights expressions that operate directly on a promise object in a nonsensical way, instead of awaiting its result. Results are shown on LGTM by default. |
46+
| Polynomial regular expression used on uncontrolled data (`js/polynomial-redos`) | security, external/cwe/cwe-730, external/cwe/cwe-400 | Highlights expensive regular expressions that may be used on malicious input. Results are shown on LGTM by default. |
4647
| Prototype pollution in utility function (`js/prototype-pollution-utility`) | security, external/cwe/cwe-400, external/cwe/cwe-471 | Highlights recursive copying operations that are susceptible to prototype pollution. Results are shown on LGTM by default. |
4748
| Unsafe jQuery plugin (`js/unsafe-jquery-plugin`) | Highlights potential XSS vulnerabilities in unsafely designed jQuery plugins. Results are shown on LGTM by default. |
4849

javascript/ql/src/AngularJS/DependencyMismatch.ql

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,9 @@ where
2424
exists(string n | p = f.getDependencyParameter(n) |
2525
p.getName() != n and
2626
exists(f.getDependencyParameter(p.getName())) and
27-
msg = "This parameter is named '" + p.getName() + "', " +
28-
"but actually refers to dependency '" + n + "'."
27+
msg =
28+
"This parameter is named '" + p.getName() + "', " + "but actually refers to dependency '" +
29+
n + "'."
2930
)
3031
)
3132
select p, msg

javascript/ql/src/AngularJS/DoubleCompilation.ql

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,8 @@ import javascript
1515
from AngularJS::ServiceReference compile, SimpleParameter elem, CallExpr c
1616
where
1717
compile.getName() = "$compile" and
18-
elem = any(AngularJS::CustomDirective d)
18+
elem =
19+
any(AngularJS::CustomDirective d)
1920
.getALinkFunction()
2021
.(AngularJS::LinkFunction)
2122
.getElementParameter() and

javascript/ql/src/AngularJS/IncompatibleService.ql

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,8 @@ where
130130
kind = getServiceKind(request, name) and
131131
exists(request.getAServiceDefinition(name)) and // ignore unknown/undefined services
132132
not isCompatibleRequestedService(request, kind) and
133-
compatibleWithString = concat(string compatibleKind |
133+
compatibleWithString =
134+
concat(string compatibleKind |
134135
isCompatibleRequestedService(request, compatibleKind) and
135136
not isWildcardKind(compatibleKind)
136137
|

javascript/ql/src/AngularJS/UnusedAngularDependency.ql

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,9 @@ predicate isMissingParameter(AngularJS::InjectableFunction f, string msg, ASTNod
3434
then dependenciesAreString = "dependency is"
3535
else dependenciesAreString = "dependencies are"
3636
) and
37-
msg = "This function has " + paramCount + " " + parametersString + ", but " + injectionCount +
38-
" " + dependenciesAreString + " injected into it."
37+
msg =
38+
"This function has " + paramCount + " " + parametersString + ", but " + injectionCount + " "
39+
+ dependenciesAreString + " injected into it."
3940
)
4041
)
4142
}

javascript/ql/src/Declarations/Declarations.qll

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,8 @@ VarRef refInContainer(Variable var, RefKind kind, StmtContainer sc) {
3131
* declaration of `var` (if `kind` is `Decl()`) in `sc`.
3232
*/
3333
VarRef firstRefInContainer(Variable var, RefKind kind, StmtContainer sc) {
34-
result = min(refInContainer(var, kind, sc) as ref
34+
result =
35+
min(refInContainer(var, kind, sc) as ref
3536
order by
3637
ref.getLocation().getStartLine(), ref.getLocation().getStartColumn()
3738
)
@@ -52,7 +53,8 @@ VarRef refInTopLevel(Variable var, RefKind kind, TopLevel tl) {
5253
* declaration of `var` (if `kind` is `Decl()`) in `tl`.
5354
*/
5455
VarRef firstRefInTopLevel(Variable var, RefKind kind, TopLevel tl) {
55-
result = min(refInTopLevel(var, kind, tl) as ref
56+
result =
57+
min(refInTopLevel(var, kind, tl) as ref
5658
order by
5759
ref.getLocation().getStartLine(), ref.getLocation().getStartColumn()
5860
)

javascript/ql/src/Declarations/MissingVarDecl.ql

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,8 @@ GlobalVarAccess getAccessIn(GlobalVariable v, Function f) {
5757
* Gets the (lexically) first access to variable `v` in function `f`.
5858
*/
5959
GlobalVarAccess getFirstAccessIn(GlobalVariable v, Function f) {
60-
result = min(getAccessIn(v, f) as gva
60+
result =
61+
min(getAccessIn(v, f) as gva
6162
order by
6263
gva.getLocation().getStartLine(), gva.getLocation().getStartColumn()
6364
)
Lines changed: 17 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
/**
22
* @name Suspicious method name declaration
3-
* @description A method declaration with a name that is a special keyword in another
4-
* context is suspicious.
3+
* @description A method declaration with a name that is a special keyword in another
4+
* context is suspicious.
55
* @kind problem
66
* @problem.severity warning
77
* @id js/suspicious-method-name-declaration
@@ -19,7 +19,7 @@ import javascript
1919
predicate isSuspiciousMethodName(string name, ClassOrInterface container) {
2020
name = "function"
2121
or
22-
// "constructor" is only suspicious outside a class.
22+
// "constructor" is only suspicious outside a class.
2323
name = "constructor" and not container instanceof ClassDefinition
2424
or
2525
// "new" is only suspicious inside a class.
@@ -31,39 +31,41 @@ where
3131
container.getLocation().getFile().getFileType().isTypeScript() and
3232
container.getMember(name) = member and
3333
isSuspiciousMethodName(name, container) and
34-
3534
// Cases to ignore.
3635
not (
3736
// Assume that a "new" method is intentional if the class has an explicit constructor.
3837
name = "new" and
3938
container instanceof ClassDefinition and
4039
exists(ConstructorDeclaration constructor |
4140
container.getMember("constructor") = constructor and
42-
not constructor.isSynthetic()
43-
)
41+
not constructor.isSynthetic()
42+
)
4443
or
4544
// Explicitly declared static methods are fine.
4645
container instanceof ClassDefinition and
4746
member.isStatic()
4847
or
49-
// Only looking for declared methods. Methods with a body are OK.
48+
// Only looking for declared methods. Methods with a body are OK.
5049
exists(member.getBody().getBody())
5150
or
5251
// The developer was not confused about "function" when there are other methods in the interface.
53-
name = "function" and
52+
name = "function" and
5453
exists(MethodDeclaration other | other = container.getAMethod() |
5554
other.getName() != "function" and
5655
not other.(ConstructorDeclaration).isSynthetic()
5756
)
58-
)
59-
60-
and
61-
57+
) and
6258
(
63-
name = "constructor" and msg = "The member name 'constructor' does not declare a constructor in interfaces, but it does in classes."
59+
name = "constructor" and
60+
msg =
61+
"The member name 'constructor' does not declare a constructor in interfaces, but it does in classes."
6462
or
65-
name = "new" and msg = "The member name 'new' does not declare a constructor, but 'constructor' does in class declarations."
63+
name = "new" and
64+
msg =
65+
"The member name 'new' does not declare a constructor, but 'constructor' does in class declarations."
6666
or
67-
name = "function" and msg = "The member name 'function' does not declare a function, it declares a method named 'function'."
67+
name = "function" and
68+
msg =
69+
"The member name 'function' does not declare a function, it declares a method named 'function'."
6870
)
6971
select member, msg

javascript/ql/src/Declarations/UnreachableMethodOverloads.ql

Lines changed: 29 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -44,43 +44,39 @@ string getKind(MemberDeclaration m) {
4444
* A call-signature that originates from a MethodSignature in the AST.
4545
*/
4646
private class MethodCallSig extends CallSignatureType {
47-
string name;
48-
49-
MethodCallSig() {
50-
exists(MethodSignature sig |
51-
this = sig.getBody().getCallSignature() and
52-
name = sig.getName()
53-
)
54-
}
55-
56-
/**
57-
* Gets the name of any member that has this signature.
58-
*/
59-
string getName() {
60-
result = name
61-
}
47+
string name;
48+
49+
MethodCallSig() {
50+
exists(MethodSignature sig |
51+
this = sig.getBody().getCallSignature() and
52+
name = sig.getName()
53+
)
54+
}
55+
56+
/**
57+
* Gets the name of any member that has this signature.
58+
*/
59+
string getName() { result = name }
6260
}
6361

6462
/**
6563
* Holds if the two call signatures could be overloads of each other and have the same parameter types.
6664
*/
6765
predicate matchingCallSignature(MethodCallSig method, MethodCallSig other) {
68-
method.getName() = other.getName() and
69-
66+
method.getName() = other.getName() and
7067
method.getNumOptionalParameter() = other.getNumOptionalParameter() and
7168
method.getNumParameter() = other.getNumParameter() and
7269
method.getNumRequiredParameter() = other.getNumRequiredParameter() and
73-
// purposely not looking at number of type arguments.
74-
75-
method.getKind() = other.getKind() and
76-
77-
78-
forall(int i | i in [0 .. -1 + method.getNumParameter()] |
70+
// purposely not looking at number of type arguments.
71+
method.getKind() = other.getKind() and
72+
forall(int i | i in [0 .. -1 + method.getNumParameter()] |
7973
method.getParameter(i) = other.getParameter(i) // This is sometimes imprecise, so it is still a good idea to compare type annotations.
80-
) and
81-
82-
// shared type parameters are equal.
83-
forall(int i | i in [0 .. -1 + min(int num | num = method.getNumTypeParameter() or num = other.getNumTypeParameter())] |
74+
) and
75+
// shared type parameters are equal.
76+
forall(int i |
77+
i in [0 .. -1 +
78+
min(int num | num = method.getNumTypeParameter() or num = other.getNumTypeParameter())]
79+
|
8480
method.getTypeParameterBound(i) = other.getTypeParameterBound(i)
8581
)
8682
}
@@ -89,7 +85,7 @@ predicate matchingCallSignature(MethodCallSig method, MethodCallSig other) {
8985
* Gets which overload index the MethodSignature has among the overloads of the same name.
9086
*/
9187
int getOverloadIndex(MethodSignature sig) {
92-
sig.getDeclaringType().getMethodOverload(sig.getName(), result) = sig
88+
sig.getDeclaringType().getMethodOverload(sig.getName(), result) = sig
9389
}
9490

9591
/**
@@ -100,41 +96,34 @@ predicate signaturesMatch(MethodSignature method, MethodSignature other) {
10096
method.getDeclaringType() = other.getDeclaringType() and
10197
// same static modifier.
10298
getKind(method) = getKind(other) and
103-
10499
// same name.
105100
method.getName() = other.getName() and
106-
107101
// same number of parameters.
108102
method.getBody().getNumParameter() = other.getBody().getNumParameter() and
109-
110103
// The types are compared in matchingCallSignature. This is sanity-check that the textual representation of the type-annotations are somewhat similar.
111104
forall(int i | i in [0 .. -1 + method.getBody().getNumParameter()] |
112-
getParameterTypeAnnotation(method, i) = getParameterTypeAnnotation(other, i)
105+
getParameterTypeAnnotation(method, i) = getParameterTypeAnnotation(other, i)
113106
) and
114-
115107
matchingCallSignature(method.getBody().getCallSignature(), other.getBody().getCallSignature())
116108
}
117109

118110
from ClassOrInterface decl, string name, MethodSignature previous, MethodSignature unreachable
119111
where
120112
previous = decl.getMethod(name) and
121113
unreachable = getOtherMatchingSignatures(previous) and
122-
123114
// If the method is part of inheritance between classes/interfaces, then there can sometimes be reasons for having this pattern.
124-
not exists(decl.getASuperTypeDeclaration().getMethod(name)) and
125-
not exists(ClassOrInterface sub |
115+
not exists(decl.getASuperTypeDeclaration().getMethod(name)) and
116+
not exists(ClassOrInterface sub |
126117
decl = sub.getASuperTypeDeclaration() and
127118
exists(sub.getMethod(name))
128119
) and
129-
130-
131120
// If a later method overload has more type parameters, then that overload can be selected by explicitly declaring the type arguments at the callsite.
132121
// This comparison removes those cases.
133122
unreachable.getBody().getNumTypeParameter() <= previous.getBody().getNumTypeParameter() and
134-
135123
// We always select the first of the overloaded methods.
136124
not exists(MethodSignature later | later = getOtherMatchingSignatures(previous) |
137125
getOverloadIndex(later) < getOverloadIndex(previous)
138126
)
139127
select unreachable,
140-
"This overload of " + name + "() is unreachable, the $@ overload will always be selected.", previous, "previous"
128+
"This overload of " + name + "() is unreachable, the $@ overload will always be selected.",
129+
previous, "previous"

javascript/ql/src/Declarations/UnstableCyclicImport.ql

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,8 @@ class CandidateVarAccess extends VarAccess {
7474
* We use this to avoid duplicate alerts about the same underlying cyclic import.
7575
*/
7676
VarAccess getFirstCandidateAccess(ImportDeclaration decl) {
77-
result = min(decl.getASpecifier().getLocal().getVariable().getAnAccess().(CandidateVarAccess) as p
77+
result =
78+
min(decl.getASpecifier().getLocal().getVariable().getAnAccess().(CandidateVarAccess) as p
7879
order by
7980
p.getFirstToken().getIndex()
8081
)
@@ -133,14 +134,15 @@ string pathToModule(Module source, Module destination, int steps) {
133134
steps > 1 and
134135
exists(Module next |
135136
// Only extend the path to one of the potential successors, as we only need one example.
136-
next = min(Module mod |
137+
next =
138+
min(Module mod |
137139
isImportedAtRuntime(source, mod) and
138140
numberOfStepsToModule(mod, destination, steps - 1)
139141
|
140142
mod order by mod.getName()
141143
) and
142-
result = repr(getARuntimeImport(source, next)) + " => " +
143-
pathToModule(next, destination, steps - 1)
144+
result =
145+
repr(getARuntimeImport(source, next)) + " => " + pathToModule(next, destination, steps - 1)
144146
)
145147
)
146148
}

0 commit comments

Comments
 (0)