Skip to content

Commit 9e3a6e8

Browse files
committed
Merge remote-tracking branch 'upstream/master' into csharp/dataflow/arrays
2 parents 795c578 + 50cd759 commit 9e3a6e8

File tree

320 files changed

+17362
-2417
lines changed

Some content is hidden

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

320 files changed

+17362
-2417
lines changed

change-notes/1.25/analysis-javascript.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
- [Promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise)
77
- [bluebird](http://bluebirdjs.com/)
88
- [express](https://www.npmjs.com/package/express)
9+
- [fancy-log](https://www.npmjs.com/package/fancy-log)
910
- [fastify](https://www.npmjs.com/package/fastify)
1011
- [fstream](https://www.npmjs.com/package/fstream)
1112
- [jGrowl](https://github.com/stanlemon/jGrowl)
@@ -22,6 +23,7 @@
2223
- [sqlite](https://www.npmjs.com/package/sqlite)
2324
- [ssh2-streams](https://www.npmjs.com/package/ssh2-streams)
2425
- [ssh2](https://www.npmjs.com/package/ssh2)
26+
- [vue](https://www.npmjs.com/package/vue)
2527
- [yargs](https://www.npmjs.com/package/yargs)
2628
- [webpack-dev-server](https://www.npmjs.com/package/webpack-dev-server)
2729

config/opcode-qldoc.py

Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
#!/usr/bin/env python3
2+
3+
import os
4+
import re
5+
path = os.path
6+
7+
needs_an_re = re.compile(r'^(?!Unary)[AEIOU]') # Name requiring "an" instead of "a".
8+
start_qldoc_re = re.compile(r'^\s*/\*\*') # Start of a QLDoc comment
9+
end_qldoc_re = re.compile(r'\*/\s*$') # End of a QLDoc comment
10+
blank_qldoc_line_re = re.compile(r'^\s*\*\s*$') # A line in a QLDoc comment with only the '*'
11+
instruction_class_re = re.compile(r'^class (?P<name>[A-aa-z0-9]+)Instruction\s') # Declaration of an `Instruction` class
12+
opcode_base_class_re = re.compile(r'^abstract class (?P<name>[A-aa-z0-9]+)Opcode\s') # Declaration of an `Opcode` base class
13+
opcode_class_re = re.compile(r'^ class (?P<name>[A-aa-z0-9]+)\s') # Declaration of an `Opcode` class
14+
15+
script_dir = path.realpath(path.dirname(__file__))
16+
instruction_path = path.realpath(path.join(script_dir, '../cpp/ql/src/semmle/code/cpp/ir/implementation/raw/Instruction.qll'))
17+
opcode_path = path.realpath(path.join(script_dir, '../cpp/ql/src/semmle/code/cpp/ir/implementation/Opcode.qll'))
18+
19+
# Scan `Instruction.qll`, keeping track of the QLDoc comment attached to each declaration of a class
20+
# whose name ends with `Instruction`.
21+
instruction_comments = {}
22+
in_qldoc = False
23+
saw_blank_line_in_qldoc = False
24+
qldoc_lines = []
25+
with open(instruction_path, 'r', encoding='utf-8') as instr:
26+
for line in instr:
27+
if in_qldoc:
28+
if end_qldoc_re.search(line):
29+
qldoc_lines.append(line)
30+
in_qldoc = False
31+
elif blank_qldoc_line_re.search(line):
32+
# We're going to skip any lines after the first blank line, to avoid duplicating all
33+
# of the verbose description.
34+
saw_blank_line_in_qldoc = True
35+
elif not saw_blank_line_in_qldoc:
36+
qldoc_lines.append(line)
37+
else:
38+
if start_qldoc_re.search(line):
39+
# Starting a new QLDoc comment.
40+
saw_blank_line_in_qldoc = False
41+
qldoc_lines.append(line)
42+
if not end_qldoc_re.search(line):
43+
in_qldoc = True
44+
else:
45+
instruction_match = instruction_class_re.search(line)
46+
if instruction_match:
47+
# Found the declaration of an `Instruction` class. Record the QLDoc comments.
48+
instruction_comments[instruction_match.group('name')] = qldoc_lines
49+
qldoc_lines = []
50+
51+
# Scan `Opcode.qll`. Whenever we see the declaration of an `Opcode` class for which we have a
52+
# corresponding `Instruction` class, we'll attach a copy of the `Instruction`'s QLDoc comment.
53+
in_qldoc = False
54+
qldoc_lines = []
55+
output_lines = []
56+
with open(opcode_path, 'r', encoding='utf-8') as opcode:
57+
for line in opcode:
58+
if in_qldoc:
59+
qldoc_lines.append(line)
60+
if end_qldoc_re.search(line):
61+
in_qldoc = False
62+
else:
63+
if start_qldoc_re.search(line):
64+
qldoc_lines.append(line)
65+
if not end_qldoc_re.search(line):
66+
in_qldoc = True
67+
else:
68+
name_without_suffix = None
69+
name = None
70+
indent = ''
71+
opcode_base_match = opcode_base_class_re.search(line)
72+
if opcode_base_match:
73+
name_without_suffix = opcode_base_match.group('name')
74+
name = name_without_suffix + 'Opcode'
75+
else:
76+
opcode_match = opcode_class_re.search(line)
77+
if opcode_match:
78+
name_without_suffix = opcode_match.group('name')
79+
name = name_without_suffix
80+
# Indent by two additional spaces, since opcodes are declared in the
81+
# `Opcode` module.
82+
indent = ' '
83+
84+
if name_without_suffix:
85+
# Found an `Opcode` that matches a known `Instruction`. Replace the QLDoc with
86+
# a copy of the one from the `Instruction`.
87+
if instruction_comments.get(name_without_suffix):
88+
article = 'an' if needs_an_re.search(name_without_suffix) else 'a'
89+
qldoc_lines = [
90+
indent + '/**\n',
91+
indent + ' * The `Opcode` for ' + article + ' `' + name_without_suffix + 'Instruction`.\n',
92+
indent + ' *\n',
93+
indent + ' * See the `' + name_without_suffix + 'Instruction` documentation for more details.\n',
94+
indent + ' */\n'
95+
]
96+
output_lines.extend(qldoc_lines)
97+
qldoc_lines = []
98+
output_lines.append(line)
99+
100+
# Write out the updated `Opcode.qll`
101+
with open(opcode_path, 'w', encoding='utf-8') as opcode:
102+
opcode.writelines(output_lines)

cpp/ql/src/Security/CWE/CWE-327/BrokenCryptoAlgorithm.ql

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ abstract class InsecureCryptoSpec extends Locatable {
1818
}
1919

2020
Function getAnInsecureFunction() {
21-
result.getName().regexpMatch(algorithmBlacklistRegex()) and
21+
result.getName().regexpMatch(getInsecureAlgorithmRegex()) and
2222
exists(result.getACallToThisFunction())
2323
}
2424

@@ -33,7 +33,7 @@ class InsecureFunctionCall extends InsecureCryptoSpec, FunctionCall {
3333
}
3434

3535
Macro getAnInsecureMacro() {
36-
result.getName().regexpMatch(algorithmBlacklistRegex()) and
36+
result.getName().regexpMatch(getInsecureAlgorithmRegex()) and
3737
exists(result.getAnInvocation())
3838
}
3939

cpp/ql/src/semmle/code/cpp/Class.qll

Lines changed: 14 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ private import semmle.code.cpp.internal.ResolveClass
3333
class Class extends UserType {
3434
Class() { isClass(underlyingElement(this)) }
3535

36-
override string getCanonicalQLClass() { result = "Class" }
36+
override string getAPrimaryQlClass() { result = "Class" }
3737

3838
/** Gets a child declaration of this class, struct or union. */
3939
override Declaration getADeclaration() { result = this.getAMember() }
@@ -768,7 +768,7 @@ class ClassDerivation extends Locatable, @derivation {
768768
*/
769769
Class getBaseClass() { result = getBaseType().getUnderlyingType() }
770770

771-
override string getCanonicalQLClass() { result = "ClassDerivation" }
771+
override string getAPrimaryQlClass() { result = "ClassDerivation" }
772772

773773
/**
774774
* Gets the type from which we are deriving, without resolving any
@@ -849,9 +849,7 @@ class ClassDerivation extends Locatable, @derivation {
849849
class LocalClass extends Class {
850850
LocalClass() { isLocal() }
851851

852-
override string getCanonicalQLClass() {
853-
not this instanceof LocalStruct and result = "LocalClass"
854-
}
852+
override string getAPrimaryQlClass() { not this instanceof LocalStruct and result = "LocalClass" }
855853

856854
override Function getEnclosingAccessHolder() { result = this.getEnclosingFunction() }
857855
}
@@ -872,7 +870,7 @@ class LocalClass extends Class {
872870
class NestedClass extends Class {
873871
NestedClass() { this.isMember() }
874872

875-
override string getCanonicalQLClass() {
873+
override string getAPrimaryQlClass() {
876874
not this instanceof NestedStruct and result = "NestedClass"
877875
}
878876

@@ -893,7 +891,7 @@ class NestedClass extends Class {
893891
class AbstractClass extends Class {
894892
AbstractClass() { exists(PureVirtualFunction f | this.getAMemberFunction() = f) }
895893

896-
override string getCanonicalQLClass() { result = "AbstractClass" }
894+
override string getAPrimaryQlClass() { result = "AbstractClass" }
897895
}
898896

899897
/**
@@ -934,7 +932,7 @@ class TemplateClass extends Class {
934932
exists(result.getATemplateArgument())
935933
}
936934

937-
override string getCanonicalQLClass() { result = "TemplateClass" }
935+
override string getAPrimaryQlClass() { result = "TemplateClass" }
938936
}
939937

940938
/**
@@ -955,7 +953,7 @@ class ClassTemplateInstantiation extends Class {
955953

956954
ClassTemplateInstantiation() { tc.getAnInstantiation() = this }
957955

958-
override string getCanonicalQLClass() { result = "ClassTemplateInstantiation" }
956+
override string getAPrimaryQlClass() { result = "ClassTemplateInstantiation" }
959957

960958
/**
961959
* Gets the class template from which this instantiation was instantiated.
@@ -996,7 +994,7 @@ abstract class ClassTemplateSpecialization extends Class {
996994
count(int i | exists(result.getTemplateArgument(i)))
997995
}
998996

999-
override string getCanonicalQLClass() { result = "ClassTemplateSpecialization" }
997+
override string getAPrimaryQlClass() { result = "ClassTemplateSpecialization" }
1000998
}
1001999

10021000
/**
@@ -1025,7 +1023,7 @@ class FullClassTemplateSpecialization extends ClassTemplateSpecialization {
10251023
not this instanceof ClassTemplateInstantiation
10261024
}
10271025

1028-
override string getCanonicalQLClass() { result = "FullClassTemplateSpecialization" }
1026+
override string getAPrimaryQlClass() { result = "FullClassTemplateSpecialization" }
10291027
}
10301028

10311029
/**
@@ -1064,7 +1062,7 @@ class PartialClassTemplateSpecialization extends ClassTemplateSpecialization {
10641062
count(int i | exists(getTemplateArgument(i)))
10651063
}
10661064

1067-
override string getCanonicalQLClass() { result = "PartialClassTemplateSpecialization" }
1065+
override string getAPrimaryQlClass() { result = "PartialClassTemplateSpecialization" }
10681066
}
10691067

10701068
/**
@@ -1089,7 +1087,7 @@ deprecated class Interface extends Class {
10891087
)
10901088
}
10911089

1092-
override string getCanonicalQLClass() { result = "Interface" }
1090+
override string getAPrimaryQlClass() { result = "Interface" }
10931091
}
10941092

10951093
/**
@@ -1104,7 +1102,7 @@ deprecated class Interface extends Class {
11041102
class VirtualClassDerivation extends ClassDerivation {
11051103
VirtualClassDerivation() { hasSpecifier("virtual") }
11061104

1107-
override string getCanonicalQLClass() { result = "VirtualClassDerivation" }
1105+
override string getAPrimaryQlClass() { result = "VirtualClassDerivation" }
11081106
}
11091107

11101108
/**
@@ -1124,7 +1122,7 @@ class VirtualClassDerivation extends ClassDerivation {
11241122
class VirtualBaseClass extends Class {
11251123
VirtualBaseClass() { exists(VirtualClassDerivation cd | cd.getBaseClass() = this) }
11261124

1127-
override string getCanonicalQLClass() { result = "VirtualBaseClass" }
1125+
override string getAPrimaryQlClass() { result = "VirtualBaseClass" }
11281126

11291127
/** A virtual class derivation of which this class/struct is the base. */
11301128
VirtualClassDerivation getAVirtualDerivation() { result.getBaseClass() = this }
@@ -1146,7 +1144,7 @@ class VirtualBaseClass extends Class {
11461144
class ProxyClass extends UserType {
11471145
ProxyClass() { usertypes(underlyingElement(this), _, 9) }
11481146

1149-
override string getCanonicalQLClass() { result = "ProxyClass" }
1147+
override string getAPrimaryQlClass() { result = "ProxyClass" }
11501148

11511149
/** Gets the location of the proxy class. */
11521150
override Location getLocation() { result = getTemplateParameter().getDefinitionLocation() }

cpp/ql/src/semmle/code/cpp/Declaration.qll

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,7 @@ class Declaration extends Locatable, @declaration {
124124
* To test whether this declaration has a particular name in the global
125125
* namespace, use `hasGlobalName`.
126126
*/
127-
abstract string getName();
127+
string getName() { none() } // overridden in subclasses
128128

129129
/** Holds if this declaration has the given name. */
130130
predicate hasName(string name) { name = this.getName() }
@@ -140,7 +140,7 @@ class Declaration extends Locatable, @declaration {
140140
}
141141

142142
/** Gets a specifier of this declaration. */
143-
abstract Specifier getASpecifier();
143+
Specifier getASpecifier() { none() } // overridden in subclasses
144144

145145
/** Holds if this declaration has a specifier with the given name. */
146146
predicate hasSpecifier(string name) { this.getASpecifier().hasName(name) }
@@ -156,7 +156,7 @@ class Declaration extends Locatable, @declaration {
156156
* Gets the location of a declaration entry corresponding to this
157157
* declaration.
158158
*/
159-
abstract Location getADeclarationLocation();
159+
Location getADeclarationLocation() { none() } // overridden in subclasses
160160

161161
/**
162162
* Gets the declaration entry corresponding to this declaration that is a
@@ -165,7 +165,7 @@ class Declaration extends Locatable, @declaration {
165165
DeclarationEntry getDefinition() { none() }
166166

167167
/** Gets the location of the definition, if any. */
168-
abstract Location getDefinitionLocation();
168+
Location getDefinitionLocation() { none() } // overridden in subclasses
169169

170170
/** Holds if the declaration has a definition. */
171171
predicate hasDefinition() { exists(this.getDefinition()) }
@@ -289,6 +289,8 @@ class Declaration extends Locatable, @declaration {
289289
}
290290
}
291291

292+
private class TDeclarationEntry = @var_decl or @type_decl or @fun_decl;
293+
292294
/**
293295
* A C/C++ declaration entry. For example the following code contains five
294296
* declaration entries:
@@ -304,9 +306,9 @@ class Declaration extends Locatable, @declaration {
304306
* See the comment above `Declaration` for an explanation of the relationship
305307
* between `Declaration` and `DeclarationEntry`.
306308
*/
307-
abstract class DeclarationEntry extends Locatable {
309+
class DeclarationEntry extends Locatable, TDeclarationEntry {
308310
/** Gets a specifier associated with this declaration entry. */
309-
abstract string getASpecifier();
311+
string getASpecifier() { none() } // overridden in subclasses
310312

311313
/**
312314
* Gets the name associated with the corresponding definition (where
@@ -329,10 +331,10 @@ abstract class DeclarationEntry extends Locatable {
329331
* `I.getADeclarationEntry()` returns `D`
330332
* but `D.getDeclaration()` only returns `C`
331333
*/
332-
abstract Declaration getDeclaration();
334+
Declaration getDeclaration() { none() } // overridden in subclasses
333335

334336
/** Gets the name associated with this declaration entry, if any. */
335-
abstract string getName();
337+
string getName() { none() } // overridden in subclasses
336338

337339
/**
338340
* Gets the type associated with this declaration entry.
@@ -341,7 +343,7 @@ abstract class DeclarationEntry extends Locatable {
341343
* For function declarations, get the return type of the function.
342344
* For type declarations, get the type being declared.
343345
*/
344-
abstract Type getType();
346+
Type getType() { none() } // overridden in subclasses
345347

346348
/**
347349
* Gets the type associated with this declaration entry after specifiers
@@ -359,7 +361,7 @@ abstract class DeclarationEntry extends Locatable {
359361
predicate hasSpecifier(string specifier) { getASpecifier() = specifier }
360362

361363
/** Holds if this declaration entry is a definition. */
362-
abstract predicate isDefinition();
364+
predicate isDefinition() { none() } // overridden in subclasses
363365

364366
override string toString() {
365367
if isDefinition()
@@ -371,6 +373,8 @@ abstract class DeclarationEntry extends Locatable {
371373
}
372374
}
373375

376+
private class TAccessHolder = @function or @usertype;
377+
374378
/**
375379
* A declaration that can potentially have more C++ access rights than its
376380
* enclosing element. This comprises `Class` (they have access to their own
@@ -392,7 +396,7 @@ abstract class DeclarationEntry extends Locatable {
392396
* the informal phrase "_R_ occurs in a member or friend of class C", where
393397
* `AccessHolder` corresponds to this _R_.
394398
*/
395-
abstract class AccessHolder extends Declaration {
399+
class AccessHolder extends Declaration, TAccessHolder {
396400
/**
397401
* Holds if `this` can access private members of class `c`.
398402
*
@@ -410,7 +414,7 @@ abstract class AccessHolder extends Declaration {
410414
/**
411415
* Gets the nearest enclosing `AccessHolder`.
412416
*/
413-
abstract AccessHolder getEnclosingAccessHolder();
417+
AccessHolder getEnclosingAccessHolder() { none() } // overridden in subclasses
414418

415419
/**
416420
* Holds if a base class `base` of `derived` _is accessible at_ `this` (N4140

0 commit comments

Comments
 (0)