mirror of
https://github.com/github/codeql.git
synced 2026-05-26 09:01:22 +02:00
Compare commits
71 Commits
hmac-cli-i
...
smowton/ad
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0a7d27a976 | ||
|
|
f006cd0e37 | ||
|
|
c99bad4047 | ||
|
|
df9533f46e | ||
|
|
d316ad198e | ||
|
|
9466043169 | ||
|
|
19c7f7be46 | ||
|
|
d4808a7b4a | ||
|
|
41778328c2 | ||
|
|
5de2e24e9a | ||
|
|
c2743177af | ||
|
|
3113b27606 | ||
|
|
208851cb91 | ||
|
|
5b974582e3 | ||
|
|
76663f80f0 | ||
|
|
0d71f0ab40 | ||
|
|
fa766126e5 | ||
|
|
a96223c9c1 | ||
|
|
e6b0552114 | ||
|
|
53d557c037 | ||
|
|
37f5db5baa | ||
|
|
9e3156dd1c | ||
|
|
b9b65005d6 | ||
|
|
edf8a3f810 | ||
|
|
ace60df619 | ||
|
|
8abee165a5 | ||
|
|
a040b67434 | ||
|
|
d85424d0e0 | ||
|
|
19c413d5fb | ||
|
|
ee433637f8 | ||
|
|
34c7bcadde | ||
|
|
9c4fcf4c6d | ||
|
|
b45d06df9a | ||
|
|
755b0bbcb9 | ||
|
|
61e282da84 | ||
|
|
6a28ddd9ec | ||
|
|
e140548547 | ||
|
|
309e376c6d | ||
|
|
59db0e7a0f | ||
|
|
c48a5a1294 | ||
|
|
9e46239928 | ||
|
|
417def8c8b | ||
|
|
d5a76e8c98 | ||
|
|
91af2f14b1 | ||
|
|
a1769f8036 | ||
|
|
e721094182 | ||
|
|
b8d632810e | ||
|
|
5312e4a8b5 | ||
|
|
f924d69dbd | ||
|
|
6dd3f7f113 | ||
|
|
1e445856e7 | ||
|
|
a86f0afb3c | ||
|
|
ef07aaa998 | ||
|
|
363fff2358 | ||
|
|
65457cc2e2 | ||
|
|
aa1284aa03 | ||
|
|
1e1b2e284d | ||
|
|
cebd24156c | ||
|
|
7f0fa15fbc | ||
|
|
e4247e4ef6 | ||
|
|
c463dc9d1a | ||
|
|
2e8b5f743b | ||
|
|
c793699562 | ||
|
|
fc6f42296a | ||
|
|
98dbe3aaf3 | ||
|
|
8fed9f9aa0 | ||
|
|
6ddacce27a | ||
|
|
63ef9a75c9 | ||
|
|
b1fd321b65 | ||
|
|
283a48c76d | ||
|
|
8c6c680a28 |
58
config/blame-deprecations.mjs
Normal file
58
config/blame-deprecations.mjs
Normal file
@@ -0,0 +1,58 @@
|
||||
import fs from "fs";
|
||||
import path from "path";
|
||||
import cp from "child_process";
|
||||
function* walk(dir) {
|
||||
for (const file of fs.readdirSync(dir)) {
|
||||
const filePath = path.join(dir, file);
|
||||
if (fs.statSync(filePath).isDirectory()) {
|
||||
yield* walk(filePath);
|
||||
} else {
|
||||
yield filePath;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function* deprecatedFiles(dir) {
|
||||
for (const file of walk(dir)) {
|
||||
if (file.endsWith(".ql") || file.endsWith(".qll")) {
|
||||
const contents = fs.readFileSync(file, "utf8");
|
||||
if (/\sdeprecated\s/.test(contents)) {
|
||||
yield file;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const blameRegExp =
|
||||
/^(\^?\w+)\s.+\s+(\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2} (?:\+|-)\d{4})\s+(\d+)\).*$/;
|
||||
|
||||
function* deprecationMessages(dir) {
|
||||
for (const file of deprecatedFiles(dir)) {
|
||||
const blame = cp.execFileSync("git", ["blame", "--", file]);
|
||||
const lines = blame.toString().split("\n");
|
||||
for (let i = 0; i < lines.length; i++) {
|
||||
const line = lines[i];
|
||||
if (line.includes(" deprecated ")) {
|
||||
try {
|
||||
const [_, sha, time, lineNumber] = line.match(blameRegExp);
|
||||
const date = new Date(time);
|
||||
// check if it's within the last 14 months (a year, plus 2 months for safety, in case a PR was delayed)
|
||||
if (date.getTime() >= Date.now() - 14 * 31 * 24 * 60 * 60 * 1000) {
|
||||
continue;
|
||||
}
|
||||
const message = `${file}:${lineNumber} was last updated on ${date.getFullYear()}-${date.getMonth()}-${date.getDate()}`;
|
||||
yield [message, date];
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
console.log("----");
|
||||
console.log(line);
|
||||
console.log("----");
|
||||
process.exit(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
[...deprecationMessages(".")]
|
||||
.sort((a, b) => a[1].getTime() - b[1].getTime())
|
||||
.forEach((msg) => console.log(msg[0]));
|
||||
@@ -0,0 +1,4 @@
|
||||
---
|
||||
category: minorAnalysis
|
||||
---
|
||||
* All deprecated predicates/classes/modules that have been deprecated for over a year have been deleted.
|
||||
@@ -69,6 +69,4 @@ import semmle.code.cpp.Comments
|
||||
import semmle.code.cpp.Preprocessor
|
||||
import semmle.code.cpp.Iteration
|
||||
import semmle.code.cpp.NameQualifiers
|
||||
import semmle.code.cpp.ObjectiveC
|
||||
import semmle.code.cpp.exprs.ObjectiveC
|
||||
import DefaultOptions
|
||||
|
||||
@@ -111,24 +111,6 @@ class Class extends UserType {
|
||||
result = this.getCanonicalMember(index).(TemplateVariable).getAnInstantiation()
|
||||
}
|
||||
|
||||
/**
|
||||
* DEPRECATED: Use `getCanonicalMember(int)` or `getAMember(int)` instead.
|
||||
* Gets the `index`th member of this class.
|
||||
*/
|
||||
deprecated Declaration getMember(int index) {
|
||||
member(underlyingElement(this), index, unresolveElement(result))
|
||||
}
|
||||
|
||||
/**
|
||||
* DEPRECATED: As this includes a somewhat arbitrary number of
|
||||
* template instantiations, it is unlikely to do what
|
||||
* you need.
|
||||
* Gets the number of members that this class has. This includes both
|
||||
* templates that are in this class, and instantiations of those
|
||||
* templates.
|
||||
*/
|
||||
deprecated int getNumMember() { result = count(this.getAMember()) }
|
||||
|
||||
/**
|
||||
* Gets a private member declared in this class, struct or union.
|
||||
* For template members, this may be either the template or an
|
||||
@@ -208,23 +190,6 @@ class Class extends UserType {
|
||||
*/
|
||||
deprecated predicate hasCopyConstructor() { this.getAMemberFunction() instanceof CopyConstructor }
|
||||
|
||||
/**
|
||||
* Holds if this class has a copy assignment operator that is either
|
||||
* explicitly declared (though possibly `= delete`) or is auto-generated,
|
||||
* non-trivial and called from somewhere.
|
||||
*
|
||||
* DEPRECATED: There is more than one reasonable definition of what it means
|
||||
* to have a copy assignment operator, and we do not want to promote one
|
||||
* particular definition by naming it with this predicate. Having a copy
|
||||
* assignment operator could mean that such a member is declared or defined
|
||||
* in the source or that it is callable by a particular caller. For C++11,
|
||||
* there's also a question of whether to include members that are defaulted
|
||||
* or deleted.
|
||||
*/
|
||||
deprecated predicate hasCopyAssignmentOperator() {
|
||||
this.getAMemberFunction() instanceof CopyAssignmentOperator
|
||||
}
|
||||
|
||||
/**
|
||||
* Like accessOfBaseMember but returns multiple results if there are multiple
|
||||
* paths to `base` through the inheritance graph.
|
||||
@@ -1070,31 +1035,6 @@ class PartialClassTemplateSpecialization extends ClassTemplateSpecialization {
|
||||
override string getAPrimaryQlClass() { result = "PartialClassTemplateSpecialization" }
|
||||
}
|
||||
|
||||
/**
|
||||
* An "interface" is a class that only contains pure virtual functions (and contains
|
||||
* at least one such function). For example:
|
||||
* ```
|
||||
* class MyInterfaceClass {
|
||||
* public:
|
||||
* virtual void myMethod1() = 0;
|
||||
* virtual void myMethod2() = 0;
|
||||
* };
|
||||
* ```
|
||||
*
|
||||
* DEPRECATED: This class is considered to be too specific for general usage.
|
||||
*/
|
||||
deprecated class Interface extends Class {
|
||||
Interface() {
|
||||
forex(Declaration m |
|
||||
m.getDeclaringType() = this.getABaseClass*() and not compgenerated(unresolveElement(m))
|
||||
|
|
||||
m instanceof PureVirtualFunction
|
||||
)
|
||||
}
|
||||
|
||||
override string getAPrimaryQlClass() { result = "Interface" }
|
||||
}
|
||||
|
||||
/**
|
||||
* A class/struct derivation that is virtual. For example the derivation in
|
||||
* the following code is a `VirtualClassDerivation`:
|
||||
|
||||
@@ -55,9 +55,6 @@ class ElementBase extends @element {
|
||||
cached
|
||||
string toString() { none() }
|
||||
|
||||
/** DEPRECATED: use `getAPrimaryQlClass` instead. */
|
||||
deprecated string getCanonicalQLClass() { result = this.getAPrimaryQlClass() }
|
||||
|
||||
/**
|
||||
* Gets a comma-separated list of the names of the primary CodeQL classes to which this element belongs.
|
||||
*/
|
||||
@@ -91,13 +88,6 @@ class Element extends ElementBase {
|
||||
*/
|
||||
predicate fromSource() { this.getFile().fromSource() }
|
||||
|
||||
/**
|
||||
* Holds if this element may be from a library.
|
||||
*
|
||||
* DEPRECATED: always true.
|
||||
*/
|
||||
deprecated predicate fromLibrary() { this.getFile().fromLibrary() }
|
||||
|
||||
/** Gets the primary location of this element. */
|
||||
Location getLocation() { none() }
|
||||
|
||||
|
||||
@@ -196,31 +196,11 @@ class Folder extends Container, @folder {
|
||||
*/
|
||||
deprecated string getName() { folders(underlyingElement(this), result) }
|
||||
|
||||
/**
|
||||
* DEPRECATED: use `getAbsolutePath` instead.
|
||||
* Holds if this element is named `name`.
|
||||
*/
|
||||
deprecated predicate hasName(string name) { name = this.getName() }
|
||||
|
||||
/**
|
||||
* DEPRECATED: use `getAbsolutePath` instead.
|
||||
* Gets the full name of this folder.
|
||||
*/
|
||||
deprecated string getFullName() { result = this.getName() }
|
||||
|
||||
/**
|
||||
* DEPRECATED: use `getBaseName` instead.
|
||||
* Gets the last part of the folder name.
|
||||
*/
|
||||
deprecated string getShortName() { result = this.getBaseName() }
|
||||
|
||||
/**
|
||||
* DEPRECATED: use `getParentContainer` instead.
|
||||
* Gets the parent folder.
|
||||
*/
|
||||
deprecated Folder getParent() {
|
||||
containerparent(unresolveElement(result), underlyingElement(this))
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -308,13 +288,6 @@ class File extends Container, @file {
|
||||
*/
|
||||
override predicate fromSource() { numlines(underlyingElement(this), _, _, _) }
|
||||
|
||||
/**
|
||||
* Holds if this file may be from a library.
|
||||
*
|
||||
* DEPRECATED: For historical reasons this is true for any file.
|
||||
*/
|
||||
deprecated override predicate fromLibrary() { any() }
|
||||
|
||||
/** Gets the metric file. */
|
||||
MetricFile getMetrics() { result = this }
|
||||
|
||||
@@ -428,25 +401,3 @@ class CppFile extends File {
|
||||
|
||||
override string getAPrimaryQlClass() { result = "CppFile" }
|
||||
}
|
||||
|
||||
/**
|
||||
* DEPRECATED: Objective-C is no longer supported.
|
||||
* An Objective C source file, as determined by file extension.
|
||||
*
|
||||
* For the related notion of whether a file is compiled as Objective C
|
||||
* code, use `File.compiledAsObjC`.
|
||||
*/
|
||||
deprecated class ObjCFile extends File {
|
||||
ObjCFile() { none() }
|
||||
}
|
||||
|
||||
/**
|
||||
* DEPRECATED: Objective-C is no longer supported.
|
||||
* An Objective C++ source file, as determined by file extension.
|
||||
*
|
||||
* For the related notion of whether a file is compiled as Objective C++
|
||||
* code, use `File.compiledAsObjCpp`.
|
||||
*/
|
||||
deprecated class ObjCppFile extends File {
|
||||
ObjCppFile() { none() }
|
||||
}
|
||||
|
||||
@@ -105,25 +105,6 @@ class Location extends @location {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* DEPRECATED: Use `Location` instead.
|
||||
* A location of an element. Not used for expressions or statements, which
|
||||
* instead use LocationExpr and LocationStmt respectively.
|
||||
*/
|
||||
deprecated library class LocationDefault extends Location, @location_default { }
|
||||
|
||||
/**
|
||||
* DEPRECATED: Use `Location` instead.
|
||||
* A location of a statement.
|
||||
*/
|
||||
deprecated library class LocationStmt extends Location, @location_stmt { }
|
||||
|
||||
/**
|
||||
* DEPRECATED: Use `Location` instead.
|
||||
* A location of an expression.
|
||||
*/
|
||||
deprecated library class LocationExpr extends Location, @location_expr { }
|
||||
|
||||
/**
|
||||
* Gets the length of the longest line in file `f`.
|
||||
*/
|
||||
|
||||
@@ -30,16 +30,6 @@ class Macro extends PreprocessorDirective, @ppd_define {
|
||||
else result = "#define " + this.getHead() + " " + this.getBody()
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if the body of the macro starts with an unmatched closing
|
||||
* parenthesis. For example:
|
||||
*
|
||||
* #define RPAREN() )
|
||||
*
|
||||
* DEPRECATED: This predicate has a misleading name.
|
||||
*/
|
||||
deprecated predicate isFunctionLike() { this.getBody().regexpMatch("[^(]*\\).*") }
|
||||
|
||||
/**
|
||||
* Gets the name of the macro. For example, `MAX` in
|
||||
* `#define MAX(x,y) (((x)>(y))?(x):(y))`.
|
||||
@@ -261,46 +251,6 @@ class MacroInvocation extends MacroAccess {
|
||||
string getExpandedArgument(int i) { macro_argument_expanded(underlyingElement(this), i, result) }
|
||||
}
|
||||
|
||||
/**
|
||||
* A top-level expression generated by a macro invocation.
|
||||
*
|
||||
* DEPRECATED: Use `MacroInvocation.getExpr()` directly to get an
|
||||
* expression generated at the top-level of a macro invocation. Use
|
||||
* `MacroInvocation.getAnAffectedElement()` to get any element generated
|
||||
* by a macro invocation.
|
||||
*/
|
||||
deprecated class MacroInvocationExpr extends Expr {
|
||||
MacroInvocationExpr() { exists(MacroInvocation i | this = i.getExpr()) }
|
||||
|
||||
/**
|
||||
* Gets the macro invocation of which this is the top-level expression.
|
||||
*/
|
||||
MacroInvocation getInvocation() { result.getExpr() = this }
|
||||
|
||||
/** Gets the name of the invoked macro. */
|
||||
string getMacroName() { result = this.getInvocation().getMacroName() }
|
||||
}
|
||||
|
||||
/**
|
||||
* A top-level statement generated by a macro invocation.
|
||||
*
|
||||
* DEPRECATED: Use `MacroInvocation.getStmt()` directly to get a
|
||||
* statement generated at the top-level of a macro invocation. Use
|
||||
* `MacroInvocation.getAnAffectedElement()` to get any element generated
|
||||
* by a macro invocation.
|
||||
*/
|
||||
deprecated class MacroInvocationStmt extends Stmt {
|
||||
MacroInvocationStmt() { exists(MacroInvocation i | this = i.getStmt()) }
|
||||
|
||||
/**
|
||||
* Gets the macro invocation of which this is the top-level statement.
|
||||
*/
|
||||
MacroInvocation getInvocation() { result.getStmt() = this }
|
||||
|
||||
/** Gets the name of the invoked macro. */
|
||||
string getMacroName() { result = this.getInvocation().getMacroName() }
|
||||
}
|
||||
|
||||
/** Holds if `l` is the location of a macro. */
|
||||
predicate macroLocation(Location l) { macrolocationbind(_, l) }
|
||||
|
||||
|
||||
@@ -233,40 +233,6 @@ class ImplicitConversionFunction extends MemberFunction {
|
||||
Type getDestType() { none() } // overridden in subclasses
|
||||
}
|
||||
|
||||
/**
|
||||
* DEPRECATED: as of C++11 this class does not correspond perfectly with the
|
||||
* language definition of a converting constructor.
|
||||
*
|
||||
* A C++ constructor that also defines an implicit conversion. For example the
|
||||
* function `MyClass` in the following code is a `ConversionConstructor`:
|
||||
* ```
|
||||
* class MyClass {
|
||||
* public:
|
||||
* MyClass(const MyOtherClass &from) {
|
||||
* ...
|
||||
* }
|
||||
* };
|
||||
* ```
|
||||
*/
|
||||
deprecated class ConversionConstructor extends Constructor, ImplicitConversionFunction {
|
||||
ConversionConstructor() {
|
||||
strictcount(Parameter p | p = this.getAParameter() and not p.hasInitializer()) = 1 and
|
||||
not this.hasSpecifier("explicit")
|
||||
}
|
||||
|
||||
override string getAPrimaryQlClass() {
|
||||
not this instanceof CopyConstructor and
|
||||
not this instanceof MoveConstructor and
|
||||
result = "ConversionConstructor"
|
||||
}
|
||||
|
||||
/** Gets the type this `ConversionConstructor` takes as input. */
|
||||
override Type getSourceType() { result = this.getParameter(0).getType() }
|
||||
|
||||
/** Gets the type this `ConversionConstructor` is a constructor of. */
|
||||
override Type getDestType() { result = this.getDeclaringType() }
|
||||
}
|
||||
|
||||
private predicate hasCopySignature(MemberFunction f) {
|
||||
f.getParameter(0).getUnspecifiedType().(LValueReferenceType).getBaseType() = f.getDeclaringType()
|
||||
}
|
||||
|
||||
@@ -86,13 +86,6 @@ class Namespace extends NameQualifyingElement, @namespace {
|
||||
/** Holds if this namespace may be from source. */
|
||||
override predicate fromSource() { this.getADeclaration().fromSource() }
|
||||
|
||||
/**
|
||||
* Holds if this namespace is in a library.
|
||||
*
|
||||
* DEPRECATED: never holds.
|
||||
*/
|
||||
deprecated override predicate fromLibrary() { not this.fromSource() }
|
||||
|
||||
/** Gets the metric namespace. */
|
||||
MetricNamespace getMetrics() { result = this }
|
||||
|
||||
@@ -233,11 +226,6 @@ class GlobalNamespace extends Namespace {
|
||||
|
||||
override Namespace getParentNamespace() { none() }
|
||||
|
||||
/**
|
||||
* DEPRECATED: use `getName()`.
|
||||
*/
|
||||
deprecated string getFullName() { result = this.getName() }
|
||||
|
||||
override string getFriendlyName() { result = "(global namespace)" }
|
||||
}
|
||||
|
||||
|
||||
@@ -1,196 +0,0 @@
|
||||
/**
|
||||
* DEPRECATED: Objective-C is no longer supported.
|
||||
*/
|
||||
|
||||
import semmle.code.cpp.Class
|
||||
private import semmle.code.cpp.internal.ResolveClass
|
||||
|
||||
/**
|
||||
* DEPRECATED: Objective-C is no longer supported.
|
||||
* An Objective C class.
|
||||
*/
|
||||
deprecated class ObjectiveClass extends Class {
|
||||
ObjectiveClass() { none() }
|
||||
}
|
||||
|
||||
/**
|
||||
* DEPRECATED: Objective-C is no longer supported.
|
||||
* An Objective C protocol.
|
||||
*/
|
||||
deprecated class Protocol extends Class {
|
||||
Protocol() { none() }
|
||||
|
||||
/**
|
||||
* Holds if the type implements the protocol, either because the type
|
||||
* itself does, or because it is a type conforming to the protocol.
|
||||
*/
|
||||
predicate isImplementedBy(Type t) { none() }
|
||||
}
|
||||
|
||||
/**
|
||||
* DEPRECATED: Objective-C is no longer supported.
|
||||
* A type which conforms to a protocol. Use `getAProtocol` to get a
|
||||
* protocol that this type conforms to.
|
||||
*/
|
||||
deprecated class TypeConformingToProtocol extends DerivedType {
|
||||
TypeConformingToProtocol() { none() }
|
||||
|
||||
/** Gets a protocol that this type conforms to. */
|
||||
Protocol getAProtocol() { none() }
|
||||
|
||||
/** Gets the size of this type. */
|
||||
override int getSize() { none() }
|
||||
|
||||
override int getAlignment() { none() }
|
||||
}
|
||||
|
||||
/**
|
||||
* DEPRECATED: Objective-C is no longer supported.
|
||||
* An Objective C `@autoreleasepool` statement, for example
|
||||
* `@autoreleasepool { int x; int y; }`.
|
||||
*/
|
||||
deprecated class AutoReleasePoolStmt extends Stmt {
|
||||
AutoReleasePoolStmt() { none() }
|
||||
|
||||
override string toString() { none() }
|
||||
|
||||
/** Gets the body statement of this `@autoreleasepool` statement. */
|
||||
Stmt getStmt() { none() }
|
||||
|
||||
override predicate mayBeImpure() { none() }
|
||||
|
||||
override predicate mayBeGloballyImpure() { none() }
|
||||
}
|
||||
|
||||
/**
|
||||
* DEPRECATED: Objective-C is no longer supported.
|
||||
* An Objective C `@synchronized statement`, for example
|
||||
* `@synchronized (x) { [x complicationOperation]; }`.
|
||||
*/
|
||||
deprecated class SynchronizedStmt extends Stmt {
|
||||
SynchronizedStmt() { none() }
|
||||
|
||||
override string toString() { none() }
|
||||
|
||||
/** Gets the expression which gives the object to be locked. */
|
||||
Expr getLockedObject() { none() }
|
||||
|
||||
/** Gets the body statement of this `@synchronized` statement. */
|
||||
Stmt getStmt() { none() }
|
||||
}
|
||||
|
||||
/**
|
||||
* DEPRECATED: Objective-C is no longer supported.
|
||||
* An Objective C for-in statement.
|
||||
*/
|
||||
deprecated class ForInStmt extends Loop {
|
||||
ForInStmt() { none() }
|
||||
|
||||
/**
|
||||
* Gets the condition expression of the `while` statement that the
|
||||
* `for...in` statement desugars into.
|
||||
*/
|
||||
override Expr getCondition() { none() }
|
||||
|
||||
override Expr getControllingExpr() { none() }
|
||||
|
||||
/** Gets the collection that the loop iterates over. */
|
||||
Expr getCollection() { none() }
|
||||
|
||||
/** Gets the body of the loop. */
|
||||
override Stmt getStmt() { none() }
|
||||
|
||||
override string toString() { none() }
|
||||
}
|
||||
|
||||
/**
|
||||
* DEPRECATED: Objective-C is no longer supported.
|
||||
* An Objective C category or class extension.
|
||||
*/
|
||||
deprecated class Category extends Class {
|
||||
Category() { none() }
|
||||
}
|
||||
|
||||
/**
|
||||
* DEPRECATED: Objective-C is no longer supported.
|
||||
* An Objective C class extension.
|
||||
*/
|
||||
deprecated class ClassExtension extends Category {
|
||||
ClassExtension() { none() }
|
||||
}
|
||||
|
||||
/**
|
||||
* DEPRECATED: Objective-C is no longer supported.
|
||||
* An Objective C try statement.
|
||||
*/
|
||||
deprecated class ObjcTryStmt extends TryStmt {
|
||||
ObjcTryStmt() { none() }
|
||||
|
||||
override string toString() { none() }
|
||||
|
||||
/** Gets the finally clause of this try statement, if any. */
|
||||
FinallyBlock getFinallyClause() { none() }
|
||||
}
|
||||
|
||||
/**
|
||||
* DEPRECATED: Objective-C is no longer supported.
|
||||
* An Objective C `@finally` block.
|
||||
*/
|
||||
deprecated class FinallyBlock extends BlockStmt {
|
||||
FinallyBlock() { none() }
|
||||
|
||||
/** Gets the try statement corresponding to this finally block. */
|
||||
ObjcTryStmt getTryStmt() { none() }
|
||||
}
|
||||
|
||||
/**
|
||||
* DEPRECATED: Objective-C is no longer supported.
|
||||
* An Objective C `@property`.
|
||||
*/
|
||||
deprecated class Property extends Declaration {
|
||||
Property() { none() }
|
||||
|
||||
/** Gets the name of this property. */
|
||||
override string getName() { none() }
|
||||
|
||||
/**
|
||||
* Gets nothing (provided for compatibility with Declaration).
|
||||
*
|
||||
* For the attribute list following the `@property` keyword, use
|
||||
* `getAnAttribute()`.
|
||||
*/
|
||||
override Specifier getASpecifier() { none() }
|
||||
|
||||
/**
|
||||
* Gets an attribute of this property (such as `readonly`, `nonatomic`,
|
||||
* or `getter=isEnabled`).
|
||||
*/
|
||||
Attribute getAnAttribute() { none() }
|
||||
|
||||
override Location getADeclarationLocation() { result = getLocation() }
|
||||
|
||||
override Location getDefinitionLocation() { result = getLocation() }
|
||||
|
||||
override Location getLocation() { none() }
|
||||
|
||||
/** Gets the type of this property. */
|
||||
Type getType() { none() }
|
||||
|
||||
/**
|
||||
* Gets the instance method which is called to get the value of this
|
||||
* property.
|
||||
*/
|
||||
MemberFunction getGetter() { none() }
|
||||
|
||||
/**
|
||||
* Gets the instance method which is called to set the value of this
|
||||
* property (if it is a writable property).
|
||||
*/
|
||||
MemberFunction getSetter() { none() }
|
||||
|
||||
/**
|
||||
* Gets the instance variable which stores the property value (if this
|
||||
* property was explicitly or automatically `@synthesize`d).
|
||||
*/
|
||||
MemberVariable getInstanceVariable() { none() }
|
||||
}
|
||||
@@ -95,22 +95,6 @@ class Parameter extends LocalScopeVariable, @parameter {
|
||||
else result = this.getADeclarationEntry()
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the name of this parameter in the given block (which should be
|
||||
* the body of a function with which the parameter is associated).
|
||||
*
|
||||
* DEPRECATED: this method was used in a previous implementation of
|
||||
* getName, but is no longer in use.
|
||||
*/
|
||||
deprecated string getNameInBlock(BlockStmt b) {
|
||||
exists(ParameterDeclarationEntry pde |
|
||||
pde.getFunctionDeclarationEntry().getBlock() = b and
|
||||
this.getFunction().getBlock() = b and
|
||||
pde.getVariable() = this and
|
||||
result = pde.getName()
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if this parameter has a name.
|
||||
*
|
||||
|
||||
@@ -1085,50 +1085,6 @@ class DerivedType extends Type, @derivedtype {
|
||||
override predicate involvesTemplateParameter() { this.getBaseType().involvesTemplateParameter() }
|
||||
|
||||
override Type stripType() { result = this.getBaseType().stripType() }
|
||||
|
||||
/**
|
||||
* Holds if this type has the `__autoreleasing` specifier or if it points to
|
||||
* a type with the `__autoreleasing` specifier.
|
||||
*
|
||||
* DEPRECATED: use `hasSpecifier` directly instead.
|
||||
*/
|
||||
deprecated predicate isAutoReleasing() {
|
||||
this.hasSpecifier("__autoreleasing") or
|
||||
this.(PointerType).getBaseType().hasSpecifier("__autoreleasing")
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if this type has the `__strong` specifier or if it points to
|
||||
* a type with the `__strong` specifier.
|
||||
*
|
||||
* DEPRECATED: use `hasSpecifier` directly instead.
|
||||
*/
|
||||
deprecated predicate isStrong() {
|
||||
this.hasSpecifier("__strong") or
|
||||
this.(PointerType).getBaseType().hasSpecifier("__strong")
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if this type has the `__unsafe_unretained` specifier or if it points
|
||||
* to a type with the `__unsafe_unretained` specifier.
|
||||
*
|
||||
* DEPRECATED: use `hasSpecifier` directly instead.
|
||||
*/
|
||||
deprecated predicate isUnsafeRetained() {
|
||||
this.hasSpecifier("__unsafe_unretained") or
|
||||
this.(PointerType).getBaseType().hasSpecifier("__unsafe_unretained")
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if this type has the `__weak` specifier or if it points to
|
||||
* a type with the `__weak` specifier.
|
||||
*
|
||||
* DEPRECATED: use `hasSpecifier` directly instead.
|
||||
*/
|
||||
deprecated predicate isWeak() {
|
||||
this.hasSpecifier("__weak") or
|
||||
this.(PointerType).getBaseType().hasSpecifier("__weak")
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -106,25 +106,4 @@ class NestedTypedefType extends TypedefType {
|
||||
NestedTypedefType() { this.isMember() }
|
||||
|
||||
override string getAPrimaryQlClass() { result = "NestedTypedefType" }
|
||||
|
||||
/**
|
||||
* DEPRECATED: use `.hasSpecifier("private")` instead.
|
||||
*
|
||||
* Holds if this member is private.
|
||||
*/
|
||||
deprecated predicate isPrivate() { this.hasSpecifier("private") }
|
||||
|
||||
/**
|
||||
* DEPRECATED: `.hasSpecifier("protected")` instead.
|
||||
*
|
||||
* Holds if this member is protected.
|
||||
*/
|
||||
deprecated predicate isProtected() { this.hasSpecifier("protected") }
|
||||
|
||||
/**
|
||||
* DEPRECATED: use `.hasSpecifier("public")` instead.
|
||||
*
|
||||
* Holds if this member is public.
|
||||
*/
|
||||
deprecated predicate isPublic() { this.hasSpecifier("public") }
|
||||
}
|
||||
|
||||
@@ -556,24 +556,6 @@ class MemberVariable extends Variable, @membervariable {
|
||||
private Type getAType() { membervariables(underlyingElement(this), unresolveElement(result), _) }
|
||||
}
|
||||
|
||||
/**
|
||||
* A C/C++ function pointer variable.
|
||||
*
|
||||
* DEPRECATED: use `Variable.getType() instanceof FunctionPointerType` instead.
|
||||
*/
|
||||
deprecated class FunctionPointerVariable extends Variable {
|
||||
FunctionPointerVariable() { this.getType() instanceof FunctionPointerType }
|
||||
}
|
||||
|
||||
/**
|
||||
* A C/C++ function pointer member variable.
|
||||
*
|
||||
* DEPRECATED: use `MemberVariable.getType() instanceof FunctionPointerType` instead.
|
||||
*/
|
||||
deprecated class FunctionPointerMemberVariable extends MemberVariable {
|
||||
FunctionPointerMemberVariable() { this instanceof FunctionPointerVariable }
|
||||
}
|
||||
|
||||
/**
|
||||
* A C++14 variable template. For example, in the following code the variable
|
||||
* template `v` defines a family of variables:
|
||||
|
||||
@@ -12,13 +12,6 @@ class XMLLocatable extends @xmllocatable, TXMLLocatable {
|
||||
/** Gets the source location for this element. */
|
||||
Location getLocation() { xmllocations(this, result) }
|
||||
|
||||
/**
|
||||
* DEPRECATED: Use `getLocation()` instead.
|
||||
*
|
||||
* Gets the source location for this element.
|
||||
*/
|
||||
deprecated Location getALocation() { result = this.getLocation() }
|
||||
|
||||
/**
|
||||
* Holds if this element is at the specified location.
|
||||
* The location spans column `startcolumn` of line `startline` to
|
||||
@@ -83,21 +76,6 @@ class XMLParent extends @xmlparent {
|
||||
/** Gets the number of places in the body of this XML parent where text occurs. */
|
||||
int getNumberOfCharacterSets() { result = count(int pos | xmlChars(_, _, this, pos, _, _)) }
|
||||
|
||||
/**
|
||||
* DEPRECATED: Internal.
|
||||
*
|
||||
* Append the character sequences of this XML parent from left to right, separated by a space,
|
||||
* up to a specified (zero-based) index.
|
||||
*/
|
||||
deprecated string charsSetUpTo(int n) {
|
||||
n = 0 and xmlChars(_, result, this, 0, _, _)
|
||||
or
|
||||
n > 0 and
|
||||
exists(string chars | xmlChars(_, chars, this, n, _, _) |
|
||||
result = this.charsSetUpTo(n - 1) + " " + chars
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the result of appending all the character sequences of this XML parent from
|
||||
* left to right, separated by a space.
|
||||
|
||||
@@ -2,20 +2,6 @@ import cpp
|
||||
import semmle.code.cpp.models.interfaces.Allocation
|
||||
import semmle.code.cpp.models.interfaces.Deallocation
|
||||
|
||||
/**
|
||||
* A library routine that allocates memory.
|
||||
*
|
||||
* DEPRECATED: Use the `AllocationFunction` class instead of this predicate.
|
||||
*/
|
||||
deprecated predicate allocationFunction(Function f) { f instanceof AllocationFunction }
|
||||
|
||||
/**
|
||||
* A call to a library routine that allocates memory.
|
||||
*
|
||||
* DEPRECATED: Use `AllocationExpr` instead (this also includes `new` expressions).
|
||||
*/
|
||||
deprecated predicate allocationCall(FunctionCall fc) { fc instanceof AllocationExpr }
|
||||
|
||||
/**
|
||||
* A library routine that frees memory.
|
||||
*/
|
||||
@@ -33,13 +19,6 @@ predicate freeCall(FunctionCall fc, Expr arg) { arg = fc.(DeallocationExpr).getF
|
||||
*/
|
||||
predicate isMemoryManagementExpr(Expr e) { isAllocationExpr(e) or e instanceof DeallocationExpr }
|
||||
|
||||
/**
|
||||
* Is e an allocation from stdlib.h (`malloc`, `realloc` etc)?
|
||||
*
|
||||
* DEPRECATED: Use `AllocationExpr` instead (this also includes `new` expressions).
|
||||
*/
|
||||
deprecated predicate isStdLibAllocationExpr(Expr e) { allocationCall(e) }
|
||||
|
||||
/**
|
||||
* Is e some kind of allocation (`new`, `alloc`, `realloc` etc)?
|
||||
*/
|
||||
@@ -48,19 +27,3 @@ predicate isAllocationExpr(Expr e) {
|
||||
or
|
||||
e = any(NewOrNewArrayExpr new | not exists(new.getPlacementPointer()))
|
||||
}
|
||||
|
||||
/**
|
||||
* Is e some kind of allocation (`new`, `alloc`, `realloc` etc) with a fixed size?
|
||||
*
|
||||
* DEPRECATED: Use `AllocationExpr.getSizeBytes()` instead.
|
||||
*/
|
||||
deprecated predicate isFixedSizeAllocationExpr(Expr allocExpr, int size) {
|
||||
size = allocExpr.(AllocationExpr).getSizeBytes()
|
||||
}
|
||||
|
||||
/**
|
||||
* Is e some kind of deallocation (`delete`, `free`, `realloc` etc)?
|
||||
*
|
||||
* DEPRECATED: Use `DeallocationExpr` instead.
|
||||
*/
|
||||
deprecated predicate isDeallocationExpr(Expr e) { e instanceof DeallocationExpr }
|
||||
|
||||
@@ -207,26 +207,6 @@ predicate variadicFormatter(Function f, string type, int formatParamIndex, int o
|
||||
callsVariadicFormatter(f, type, formatParamIndex, outputParamIndex)
|
||||
}
|
||||
|
||||
/**
|
||||
* A standard function such as `vprintf` that has a format parameter
|
||||
* and a variable argument list of type `va_arg`.
|
||||
*
|
||||
* DEPRECATED: Use the four argument version instead.
|
||||
*/
|
||||
deprecated predicate primitiveVariadicFormatter(TopLevelFunction f, int formatParamIndex) {
|
||||
primitiveVariadicFormatter(f, _, formatParamIndex, _)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if `f` is a function such as `vprintf` that has a format parameter
|
||||
* (at `formatParamIndex`) and a variable argument list of type `va_arg`.
|
||||
*
|
||||
* DEPRECATED: Use the four argument version instead.
|
||||
*/
|
||||
deprecated predicate variadicFormatter(Function f, int formatParamIndex) {
|
||||
variadicFormatter(f, _, formatParamIndex, _)
|
||||
}
|
||||
|
||||
/**
|
||||
* A function not in the standard library which takes a `printf`-like formatting
|
||||
* string and a variable number of arguments.
|
||||
@@ -428,13 +408,6 @@ class FormatLiteral extends Literal {
|
||||
*/
|
||||
FormattingFunctionCall getUse() { result.getFormat() = this }
|
||||
|
||||
/**
|
||||
* Holds if the default meaning of `%s` is a `wchar_t *`, rather than
|
||||
* a `char *` (either way, `%S` will have the opposite meaning).
|
||||
* DEPRECATED: Use getDefaultCharType() instead.
|
||||
*/
|
||||
deprecated predicate isWideCharDefault() { this.getUse().getTarget().isWideCharDefault() }
|
||||
|
||||
/**
|
||||
* Gets the default character type expected for `%s` by this format literal. Typically
|
||||
* `char` or `wchar_t`.
|
||||
|
||||
@@ -223,20 +223,6 @@ class BasicBlock extends ControlFlowNodeBase {
|
||||
*/
|
||||
predicate inLoop() { this.getASuccessor+() = this }
|
||||
|
||||
/**
|
||||
* DEPRECATED since version 1.11: this predicate does not match the standard
|
||||
* definition of _loop header_.
|
||||
*
|
||||
* Holds if this basic block is in a loop of the control-flow graph and
|
||||
* additionally has an incoming edge that is not part of any loop containing
|
||||
* this basic block. A typical example would be the basic block that computes
|
||||
* `x > 0` in an outermost loop `while (x > 0) { ... }`.
|
||||
*/
|
||||
deprecated predicate isLoopHeader() {
|
||||
this.inLoop() and
|
||||
exists(BasicBlock pred | pred = this.getAPredecessor() and not pred = this.getASuccessor+())
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if control flow may reach this basic block from a function entry
|
||||
* point or any handler of a reachable `try` statement.
|
||||
|
||||
@@ -94,24 +94,6 @@ import ControlFlowGraphPublic
|
||||
*/
|
||||
class ControlFlowNodeBase extends ElementBase, @cfgnode { }
|
||||
|
||||
/**
|
||||
* DEPRECATED: Use `ControlFlowNode.getATrueSuccessor()` instead.
|
||||
* Holds when `n2` is a control-flow node such that the control-flow
|
||||
* edge `(n1, n2)` may be taken when `n1` is an expression that is true.
|
||||
*/
|
||||
deprecated predicate truecond_base(ControlFlowNodeBase n1, ControlFlowNodeBase n2) {
|
||||
qlCFGTrueSuccessor(n1, n2)
|
||||
}
|
||||
|
||||
/**
|
||||
* DEPRECATED: Use `ControlFlowNode.getAFalseSuccessor()` instead.
|
||||
* Holds when `n2` is a control-flow node such that the control-flow
|
||||
* edge `(n1, n2)` may be taken when `n1` is an expression that is false.
|
||||
*/
|
||||
deprecated predicate falsecond_base(ControlFlowNodeBase n1, ControlFlowNodeBase n2) {
|
||||
qlCFGFalseSuccessor(n1, n2)
|
||||
}
|
||||
|
||||
/**
|
||||
* An abstract class that can be extended to add additional edges to the
|
||||
* control-flow graph. Instances of this class correspond to the source nodes
|
||||
|
||||
@@ -1,393 +0,0 @@
|
||||
/**
|
||||
* DEPRECATED: Use `StackVariableReachability` instead.
|
||||
*/
|
||||
|
||||
import cpp
|
||||
|
||||
/**
|
||||
* DEPRECATED: Use `StackVariableReachability` instead.
|
||||
*
|
||||
* A reachability analysis for control-flow nodes involving stack variables.
|
||||
* This defines sources, sinks, and any other configurable aspect of the
|
||||
* analysis. Multiple analyses can coexist. To create an analysis, extend this
|
||||
* class with a subclass whose characteristic predicate is a unique singleton
|
||||
* string. For example, write
|
||||
*
|
||||
* ```
|
||||
* class MyAnalysisConfiguration extends LocalScopeVariableReachability {
|
||||
* MyAnalysisConfiguration() { this = "MyAnalysisConfiguration" }
|
||||
* // Override `isSource` and `isSink`.
|
||||
* // Override `isBarrier`.
|
||||
* }
|
||||
* ```
|
||||
*
|
||||
* Then, to query whether there is flow between some source and sink, call the
|
||||
* `reaches` predicate on an instance of `MyAnalysisConfiguration`.
|
||||
*/
|
||||
abstract deprecated class LocalScopeVariableReachability extends string {
|
||||
bindingset[this]
|
||||
LocalScopeVariableReachability() { length() >= 0 }
|
||||
|
||||
/** Holds if `node` is a source for the reachability analysis using variable `v`. */
|
||||
abstract predicate isSource(ControlFlowNode node, LocalScopeVariable v);
|
||||
|
||||
/** Holds if `sink` is a (potential) sink for the reachability analysis using variable `v`. */
|
||||
abstract predicate isSink(ControlFlowNode node, LocalScopeVariable v);
|
||||
|
||||
/** Holds if `node` is a barrier for the reachability analysis using variable `v`. */
|
||||
abstract predicate isBarrier(ControlFlowNode node, LocalScopeVariable v);
|
||||
|
||||
/**
|
||||
* Holds if the source node `source` can reach the sink `sink` without crossing
|
||||
* a barrier. This is (almost) equivalent to the following QL predicate but
|
||||
* uses basic blocks internally for better performance:
|
||||
*
|
||||
* ```
|
||||
* predicate reaches(ControlFlowNode source, SemanticStackVariable v, ControlFlowNode sink) {
|
||||
* reachesImpl(source, v, sink)
|
||||
* and
|
||||
* isSink(sink, v)
|
||||
* }
|
||||
*
|
||||
* predicate reachesImpl(ControlFlowNode source, SemanticStackVariable v, ControlFlowNode sink) {
|
||||
* sink = source.getASuccessor() and isSource(source, v)
|
||||
* or
|
||||
* exists(ControlFlowNode mid | reachesImpl(source, v, mid) |
|
||||
* not isBarrier(mid, v)
|
||||
* and
|
||||
* sink = mid.getASuccessor()
|
||||
* )
|
||||
* }
|
||||
* ```
|
||||
*
|
||||
* In addition to using a better performing implementation, this analysis
|
||||
* accounts for loops where the condition is provably true upon entry.
|
||||
*/
|
||||
predicate reaches(ControlFlowNode source, SemanticStackVariable v, ControlFlowNode sink) {
|
||||
/*
|
||||
* Implementation detail: the predicates in this class are a generalization of
|
||||
* those in DefinitionsAndUses.qll, and should be kept in sync.
|
||||
*
|
||||
* Unfortunately, caching of abstract predicates does not work well, so the
|
||||
* predicates in DefinitionsAndUses.qll cannot use this library.
|
||||
*/
|
||||
|
||||
exists(BasicBlock bb, int i |
|
||||
this.isSource(source, v) and
|
||||
bb.getNode(i) = source and
|
||||
not bb.isUnreachable()
|
||||
|
|
||||
exists(int j |
|
||||
j > i and
|
||||
sink = bb.getNode(j) and
|
||||
this.isSink(sink, v) and
|
||||
not exists(int k | this.isBarrier(bb.getNode(k), v) | k in [i + 1 .. j - 1])
|
||||
)
|
||||
or
|
||||
not exists(int k | this.isBarrier(bb.getNode(k), v) | k > i) and
|
||||
this.bbSuccessorEntryReaches(bb, v, sink, _)
|
||||
)
|
||||
}
|
||||
|
||||
private predicate bbSuccessorEntryReaches(
|
||||
BasicBlock bb, SemanticStackVariable v, ControlFlowNode node,
|
||||
boolean skipsFirstLoopAlwaysTrueUponEntry
|
||||
) {
|
||||
exists(BasicBlock succ, boolean succSkipsFirstLoopAlwaysTrueUponEntry |
|
||||
bbSuccessorEntryReachesLoopInvariant(bb, succ, skipsFirstLoopAlwaysTrueUponEntry,
|
||||
succSkipsFirstLoopAlwaysTrueUponEntry)
|
||||
|
|
||||
this.bbEntryReachesLocally(succ, v, node) and
|
||||
succSkipsFirstLoopAlwaysTrueUponEntry = false
|
||||
or
|
||||
not this.isBarrier(succ.getNode(_), v) and
|
||||
this.bbSuccessorEntryReaches(succ, v, node, succSkipsFirstLoopAlwaysTrueUponEntry)
|
||||
)
|
||||
}
|
||||
|
||||
private predicate bbEntryReachesLocally(
|
||||
BasicBlock bb, SemanticStackVariable v, ControlFlowNode node
|
||||
) {
|
||||
exists(int n |
|
||||
node = bb.getNode(n) and
|
||||
this.isSink(node, v)
|
||||
|
|
||||
not exists(this.firstBarrierIndexIn(bb, v))
|
||||
or
|
||||
n <= this.firstBarrierIndexIn(bb, v)
|
||||
)
|
||||
}
|
||||
|
||||
private int firstBarrierIndexIn(BasicBlock bb, SemanticStackVariable v) {
|
||||
result = min(int m | this.isBarrier(bb.getNode(m), v))
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if `bb` contains the entry point `loop` for a loop at position `i`.
|
||||
* The condition of that loop is provably true upon entry but not provably
|
||||
* true in general (if it were, the false-successor had already been removed
|
||||
* from the CFG).
|
||||
*
|
||||
* Examples:
|
||||
* ```
|
||||
* for (int i = 0; i < 2; i++) { } // always true upon entry
|
||||
* for (int i = 0; true; i++) { } // always true
|
||||
* ```
|
||||
*/
|
||||
private predicate bbLoopEntryConditionAlwaysTrueAt(BasicBlock bb, int i, ControlFlowNode loop) {
|
||||
exists(Expr condition |
|
||||
loopConditionAlwaysTrueUponEntry(loop, condition) and
|
||||
not conditionAlwaysTrue(condition) and
|
||||
bb.getNode(i) = loop
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Basic block `pred` contains all or part of the condition belonging to a loop,
|
||||
* and there is an edge from `pred` to `succ` that concludes the condition.
|
||||
* If the edge corrseponds with the loop condition being found to be `true`, then
|
||||
* `skipsLoop` is `false`. Otherwise the edge corresponds with the loop condition
|
||||
* being found to be `false` and `skipsLoop` is `true`. Non-concluding edges
|
||||
* within a complex loop condition are not matched by this predicate.
|
||||
*/
|
||||
private predicate bbLoopConditionAlwaysTrueUponEntrySuccessor(
|
||||
BasicBlock pred, BasicBlock succ, boolean skipsLoop
|
||||
) {
|
||||
exists(Expr cond |
|
||||
loopConditionAlwaysTrueUponEntry(_, cond) and
|
||||
cond.getAChild*() = pred.getEnd() and
|
||||
succ = pred.getASuccessor() and
|
||||
not cond.getAChild*() = succ.getStart() and
|
||||
(
|
||||
succ = pred.getAFalseSuccessor() and
|
||||
skipsLoop = true
|
||||
or
|
||||
succ = pred.getATrueSuccessor() and
|
||||
skipsLoop = false
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Loop invariant for `bbSuccessorEntryReaches`:
|
||||
*
|
||||
* - `succ` is a successor of `pred`.
|
||||
* - `predSkipsFirstLoopAlwaysTrueUponEntry`: whether the path from
|
||||
* `pred` (via `succ`) skips the first loop where the condition is
|
||||
* provably true upon entry.
|
||||
* - `succSkipsFirstLoopAlwaysTrueUponEntry`: whether the path from
|
||||
* `succ` skips the first loop where the condition is provably true
|
||||
* upon entry.
|
||||
* - If `pred` contains the entry point of a loop where the condition
|
||||
* is provably true upon entry, then `succ` is not allowed to skip
|
||||
* that loop (`succSkipsFirstLoopAlwaysTrueUponEntry = false`).
|
||||
*/
|
||||
predicate bbSuccessorEntryReachesLoopInvariant(
|
||||
BasicBlock pred, BasicBlock succ, boolean predSkipsFirstLoopAlwaysTrueUponEntry,
|
||||
boolean succSkipsFirstLoopAlwaysTrueUponEntry
|
||||
) {
|
||||
succ = pred.getASuccessor() and
|
||||
(succSkipsFirstLoopAlwaysTrueUponEntry = true or succSkipsFirstLoopAlwaysTrueUponEntry = false) and
|
||||
(
|
||||
// The edge from `pred` to `succ` is from a loop condition provably
|
||||
// true upon entry, so the value of `predSkipsFirstLoopAlwaysTrueUponEntry`
|
||||
// is determined by whether the true edge or the false edge is chosen,
|
||||
// regardless of the value of `succSkipsFirstLoopAlwaysTrueUponEntry`.
|
||||
bbLoopConditionAlwaysTrueUponEntrySuccessor(pred, succ, predSkipsFirstLoopAlwaysTrueUponEntry)
|
||||
or
|
||||
// The edge from `pred` to `succ` is _not_ from a loop condition provably
|
||||
// true upon entry, so the values of `predSkipsFirstLoopAlwaysTrueUponEntry`
|
||||
// and `succSkipsFirstLoopAlwaysTrueUponEntry` must be the same.
|
||||
not bbLoopConditionAlwaysTrueUponEntrySuccessor(pred, succ, _) and
|
||||
succSkipsFirstLoopAlwaysTrueUponEntry = predSkipsFirstLoopAlwaysTrueUponEntry and
|
||||
// Moreover, if `pred` contains the entry point of a loop where the
|
||||
// condition is provably true upon entry, then `succ` is not allowed
|
||||
// to skip that loop, and hence `succSkipsFirstLoopAlwaysTrueUponEntry = false`.
|
||||
(
|
||||
bbLoopEntryConditionAlwaysTrueAt(pred, _, _)
|
||||
implies
|
||||
succSkipsFirstLoopAlwaysTrueUponEntry = false
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* DEPRECATED: Use `StackVariableReachabilityWithReassignment` instead.
|
||||
*
|
||||
* Reachability analysis for control-flow nodes involving stack variables.
|
||||
* Unlike `LocalScopeVariableReachability`, this analysis takes variable
|
||||
* reassignments into account.
|
||||
*
|
||||
* This class is used like `LocalScopeVariableReachability`, except that
|
||||
* subclasses should override `isSourceActual` and `isSinkActual` instead of
|
||||
* `isSource` and `isSink`, and that there is a `reachesTo` predicate in
|
||||
* addition to `reaches`.
|
||||
*/
|
||||
abstract deprecated class LocalScopeVariableReachabilityWithReassignment extends LocalScopeVariableReachability {
|
||||
bindingset[this]
|
||||
LocalScopeVariableReachabilityWithReassignment() { length() >= 0 }
|
||||
|
||||
/** Override this predicate rather than `isSource` (`isSource` is used internally). */
|
||||
abstract predicate isSourceActual(ControlFlowNode node, LocalScopeVariable v);
|
||||
|
||||
/** Override this predicate rather than `isSink` (`isSink` is used internally). */
|
||||
abstract predicate isSinkActual(ControlFlowNode node, LocalScopeVariable v);
|
||||
|
||||
/**
|
||||
* Holds if the source node `source` can reach the sink `sink` without crossing
|
||||
* a barrier, taking reassignments into account. This is (almost) equivalent
|
||||
* to the following QL predicate, but uses basic blocks internally for better
|
||||
* performance:
|
||||
*
|
||||
* ```
|
||||
* predicate reaches(ControlFlowNode source, SemanticStackVariable v, ControlFlowNode sink) {
|
||||
* reachesImpl(source, v, sink)
|
||||
* and
|
||||
* isSinkActual(sink, v)
|
||||
* }
|
||||
*
|
||||
* predicate reachesImpl(ControlFlowNode source, SemanticStackVariable v, ControlFlowNode sink) {
|
||||
* isSourceActual(source, v)
|
||||
* and
|
||||
* (
|
||||
* sink = source.getASuccessor()
|
||||
* or
|
||||
* exists(ControlFlowNode mid, SemanticStackVariable v0 | reachesImpl(source, v0, mid) |
|
||||
* // ordinary successor
|
||||
* not isBarrier(mid, v) and
|
||||
* sink = mid.getASuccessor() and
|
||||
* v = v0
|
||||
* or
|
||||
* // reassigned from v0 to v
|
||||
* exprDefinition(v, mid, v0.getAnAccess()) and
|
||||
* sink = mid.getASuccessor()
|
||||
* )
|
||||
* )
|
||||
* }
|
||||
* ```
|
||||
*
|
||||
* In addition to using a better performing implementation, this analysis
|
||||
* accounts for loops where the condition is provably true upon entry.
|
||||
*/
|
||||
override predicate reaches(ControlFlowNode source, SemanticStackVariable v, ControlFlowNode sink) {
|
||||
this.reachesTo(source, v, sink, _)
|
||||
}
|
||||
|
||||
/**
|
||||
* As `reaches`, but also specifies the last variable it was reassigned to (`v0`).
|
||||
*/
|
||||
predicate reachesTo(
|
||||
ControlFlowNode source, SemanticStackVariable v, ControlFlowNode sink, SemanticStackVariable v0
|
||||
) {
|
||||
exists(ControlFlowNode def |
|
||||
this.actualSourceReaches(source, v, def, v0) and
|
||||
LocalScopeVariableReachability.super.reaches(def, v0, sink) and
|
||||
this.isSinkActual(sink, v0)
|
||||
)
|
||||
}
|
||||
|
||||
private predicate actualSourceReaches(
|
||||
ControlFlowNode source, SemanticStackVariable v, ControlFlowNode def, SemanticStackVariable v0
|
||||
) {
|
||||
this.isSourceActual(source, v) and def = source and v0 = v
|
||||
or
|
||||
exists(ControlFlowNode source1, SemanticStackVariable v1 |
|
||||
this.actualSourceReaches(source, v, source1, v1)
|
||||
|
|
||||
this.reassignment(source1, v1, def, v0)
|
||||
)
|
||||
}
|
||||
|
||||
private predicate reassignment(
|
||||
ControlFlowNode source, SemanticStackVariable v, ControlFlowNode def, SemanticStackVariable v0
|
||||
) {
|
||||
LocalScopeVariableReachability.super.reaches(source, v, def) and
|
||||
exprDefinition(v0, def, v.getAnAccess())
|
||||
}
|
||||
|
||||
final override predicate isSource(ControlFlowNode node, LocalScopeVariable v) {
|
||||
this.isSourceActual(node, v)
|
||||
or
|
||||
// Reassignment generates a new (non-actual) source
|
||||
this.reassignment(_, _, node, v)
|
||||
}
|
||||
|
||||
final override predicate isSink(ControlFlowNode node, LocalScopeVariable v) {
|
||||
this.isSinkActual(node, v)
|
||||
or
|
||||
// Reassignment generates a new (non-actual) sink
|
||||
exprDefinition(_, node, v.getAnAccess())
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* DEPRECATED: Use `StackVariableReachabilityExt` instead.
|
||||
*
|
||||
* Same as `LocalScopeVariableReachability`, but `isBarrier` works on control-flow
|
||||
* edges rather than nodes and is therefore parameterized by the original
|
||||
* source node as well. Otherwise, this class is used like
|
||||
* `LocalScopeVariableReachability`.
|
||||
*/
|
||||
abstract deprecated class LocalScopeVariableReachabilityExt extends string {
|
||||
bindingset[this]
|
||||
LocalScopeVariableReachabilityExt() { length() >= 0 }
|
||||
|
||||
/** `node` is a source for the reachability analysis using variable `v`. */
|
||||
abstract predicate isSource(ControlFlowNode node, LocalScopeVariable v);
|
||||
|
||||
/** `sink` is a (potential) sink for the reachability analysis using variable `v`. */
|
||||
abstract predicate isSink(ControlFlowNode node, LocalScopeVariable v);
|
||||
|
||||
/** `node` is a barrier for the reachability analysis using variable `v` and starting from `source`. */
|
||||
abstract predicate isBarrier(
|
||||
ControlFlowNode source, ControlFlowNode node, ControlFlowNode next, LocalScopeVariable v
|
||||
);
|
||||
|
||||
/** See `LocalScopeVariableReachability.reaches`. */
|
||||
predicate reaches(ControlFlowNode source, SemanticStackVariable v, ControlFlowNode sink) {
|
||||
exists(BasicBlock bb, int i |
|
||||
this.isSource(source, v) and
|
||||
bb.getNode(i) = source and
|
||||
not bb.isUnreachable()
|
||||
|
|
||||
exists(int j |
|
||||
j > i and
|
||||
sink = bb.getNode(j) and
|
||||
this.isSink(sink, v) and
|
||||
not exists(int k | this.isBarrier(source, bb.getNode(k), bb.getNode(k + 1), v) |
|
||||
k in [i .. j - 1]
|
||||
)
|
||||
)
|
||||
or
|
||||
not exists(int k | this.isBarrier(source, bb.getNode(k), bb.getNode(k + 1), v) | k >= i) and
|
||||
this.bbSuccessorEntryReaches(source, bb, v, sink, _)
|
||||
)
|
||||
}
|
||||
|
||||
private predicate bbSuccessorEntryReaches(
|
||||
ControlFlowNode source, BasicBlock bb, SemanticStackVariable v, ControlFlowNode node,
|
||||
boolean skipsFirstLoopAlwaysTrueUponEntry
|
||||
) {
|
||||
exists(BasicBlock succ, boolean succSkipsFirstLoopAlwaysTrueUponEntry |
|
||||
bbSuccessorEntryReachesLoopInvariant(bb, succ, skipsFirstLoopAlwaysTrueUponEntry,
|
||||
succSkipsFirstLoopAlwaysTrueUponEntry) and
|
||||
not this.isBarrier(source, bb.getEnd(), succ.getStart(), v)
|
||||
|
|
||||
this.bbEntryReachesLocally(source, succ, v, node) and
|
||||
succSkipsFirstLoopAlwaysTrueUponEntry = false
|
||||
or
|
||||
not exists(int k | this.isBarrier(source, succ.getNode(k), succ.getNode(k + 1), v)) and
|
||||
this.bbSuccessorEntryReaches(source, succ, v, node, succSkipsFirstLoopAlwaysTrueUponEntry)
|
||||
)
|
||||
}
|
||||
|
||||
private predicate bbEntryReachesLocally(
|
||||
ControlFlowNode source, BasicBlock bb, SemanticStackVariable v, ControlFlowNode node
|
||||
) {
|
||||
this.isSource(source, v) and
|
||||
exists(int n | node = bb.getNode(n) and this.isSink(node, v) |
|
||||
not exists(int m | m < n | this.isBarrier(source, bb.getNode(m), bb.getNode(m + 1), v))
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -156,15 +156,6 @@ class AnalysedExpr extends Expr {
|
||||
this.isValidCheck(v) and result = this.getATrueSuccessor()
|
||||
}
|
||||
|
||||
/**
|
||||
* DEPRECATED: Use `getNonNullSuccessor` instead, which does the same.
|
||||
*/
|
||||
deprecated ControlFlowNode getValidSuccessor(LocalScopeVariable v) {
|
||||
this.isValidCheck(v) and result = this.getATrueSuccessor()
|
||||
or
|
||||
this.isNullCheck(v) and result = this.getAFalseSuccessor()
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if this is a `VariableAccess` of `v` nested inside a condition.
|
||||
*/
|
||||
|
||||
@@ -147,15 +147,4 @@ class SsaDefinition extends ControlFlowNodeBase {
|
||||
Expr getAnUltimateDefiningValue(StackVariable v) {
|
||||
result = this.getAnUltimateSsaDefinition(v).getDefiningValue(v)
|
||||
}
|
||||
|
||||
/**
|
||||
* DEPRECATED: this is the old name for `getAnUltimateDefiningValue`. The
|
||||
* name was confusing as it seemed analogous to `getDefinition` rather than
|
||||
* `getDefiningValue`. The SSA libraries for other languages use the name
|
||||
* `getAnUltimateSsaDefinition` to refer to a predicate named
|
||||
* `getAnUltimateSsaDefinition` in this class.
|
||||
*/
|
||||
deprecated Expr getAnUltimateDefinition(StackVariable v) {
|
||||
result = this.getAnUltimateDefiningValue(v)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,9 +21,4 @@ import semmle.code.cpp.dataflow.DataFlow2
|
||||
module TaintTracking {
|
||||
import semmle.code.cpp.dataflow.internal.tainttracking1.TaintTrackingImpl
|
||||
private import semmle.code.cpp.dataflow.TaintTracking2
|
||||
|
||||
/**
|
||||
* DEPRECATED: Use TaintTracking2::Configuration instead.
|
||||
*/
|
||||
deprecated class Configuration2 = TaintTracking2::Configuration;
|
||||
}
|
||||
|
||||
@@ -113,10 +113,6 @@ private module PartialDefinitions {
|
||||
abstract class PartialDefinition extends Expr {
|
||||
ControlFlowNode node;
|
||||
|
||||
abstract deprecated predicate partiallyDefines(Variable v);
|
||||
|
||||
abstract deprecated predicate partiallyDefinesThis(ThisExpr e);
|
||||
|
||||
/**
|
||||
* Gets the subBasicBlock where this `PartialDefinition` is defined.
|
||||
*/
|
||||
@@ -189,10 +185,6 @@ private module PartialDefinitions {
|
||||
)
|
||||
}
|
||||
|
||||
deprecated override predicate partiallyDefines(Variable v) { v = collection }
|
||||
|
||||
deprecated override predicate partiallyDefinesThis(ThisExpr e) { none() }
|
||||
|
||||
override predicate definesExpressions(Expr inner, Expr outer) {
|
||||
inner = innerDefinedExpr and
|
||||
outer = this
|
||||
@@ -217,12 +209,6 @@ private module PartialDefinitions {
|
||||
|
||||
VariablePartialDefinition() { innerDefinedExpr = getInnerDefinedExpr(this, node) }
|
||||
|
||||
deprecated override predicate partiallyDefines(Variable v) {
|
||||
innerDefinedExpr = v.getAnAccess()
|
||||
}
|
||||
|
||||
deprecated override predicate partiallyDefinesThis(ThisExpr e) { innerDefinedExpr = e }
|
||||
|
||||
/**
|
||||
* Holds if this partial definition may modify `inner` (or what it points
|
||||
* to) through `outer`. These expressions will never be `Conversion`s.
|
||||
|
||||
@@ -226,13 +226,6 @@ class AssignPointerSubExpr extends AssignOperation, @assignpsubexpr {
|
||||
* ```
|
||||
*/
|
||||
class ConditionDeclExpr extends Expr, @condition_decl {
|
||||
/**
|
||||
* DEPRECATED: Use `getVariableAccess()` or `getInitializingExpr()` instead.
|
||||
*
|
||||
* Gets the access using the condition for this declaration.
|
||||
*/
|
||||
deprecated Expr getExpr() { result = this.getChild(0) }
|
||||
|
||||
override string getAPrimaryQlClass() { result = "ConditionDeclExpr" }
|
||||
|
||||
/**
|
||||
|
||||
@@ -118,11 +118,6 @@ class BuiltInNoOp extends BuiltInOperation, @noopexpr {
|
||||
override string getAPrimaryQlClass() { result = "BuiltInNoOp" }
|
||||
}
|
||||
|
||||
/**
|
||||
* DEPRECATED: Use `BuiltInOperationBuiltInOffsetOf` instead.
|
||||
*/
|
||||
deprecated class BuiltInOperationOffsetOf = BuiltInOperationBuiltInOffsetOf;
|
||||
|
||||
/**
|
||||
* A C/C++ `__builtin_offsetof` built-in operation (used by some implementations
|
||||
* of `offsetof`). The operation retains its semantics even in the presence
|
||||
@@ -465,11 +460,6 @@ class BuiltInOperationIsUnion extends BuiltInOperation, @isunionexpr {
|
||||
override string getAPrimaryQlClass() { result = "BuiltInOperationIsUnion" }
|
||||
}
|
||||
|
||||
/**
|
||||
* DEPRECATED: Use `BuiltInOperationBuiltInTypesCompatibleP` instead.
|
||||
*/
|
||||
deprecated class BuiltInOperationBuiltInTypes = BuiltInOperationBuiltInTypesCompatibleP;
|
||||
|
||||
/**
|
||||
* A C++ `__builtin_types_compatible_p` built-in operation (used by some
|
||||
* implementations of the `<type_traits>` header).
|
||||
|
||||
@@ -666,13 +666,6 @@ class TypeidOperator extends Expr, @type_id {
|
||||
*/
|
||||
Type getResultType() { typeid_bind(underlyingElement(this), unresolveElement(result)) }
|
||||
|
||||
/**
|
||||
* DEPRECATED: Use `getResultType()` instead.
|
||||
*
|
||||
* Gets the type that is returned by this typeid expression.
|
||||
*/
|
||||
deprecated Type getSpecifiedType() { result = this.getResultType() }
|
||||
|
||||
override string getAPrimaryQlClass() { result = "TypeidOperator" }
|
||||
|
||||
/**
|
||||
@@ -731,13 +724,6 @@ class SizeofExprOperator extends SizeofOperator {
|
||||
/** Gets the contained expression. */
|
||||
Expr getExprOperand() { result = this.getChild(0) }
|
||||
|
||||
/**
|
||||
* DEPRECATED: Use `getExprOperand()` instead
|
||||
*
|
||||
* Gets the contained expression.
|
||||
*/
|
||||
deprecated Expr getExpr() { result = this.getExprOperand() }
|
||||
|
||||
override string toString() { result = "sizeof(<expr>)" }
|
||||
|
||||
override predicate mayBeImpure() { this.getExprOperand().mayBeImpure() }
|
||||
@@ -759,13 +745,6 @@ class SizeofTypeOperator extends SizeofOperator {
|
||||
/** Gets the contained type. */
|
||||
Type getTypeOperand() { sizeof_bind(underlyingElement(this), unresolveElement(result)) }
|
||||
|
||||
/**
|
||||
* DEPRECATED: Use `getTypeOperand()` instead
|
||||
*
|
||||
* Gets the contained type.
|
||||
*/
|
||||
deprecated Type getSpecifiedType() { result = this.getTypeOperand() }
|
||||
|
||||
override string toString() { result = "sizeof(" + this.getTypeOperand().getName() + ")" }
|
||||
|
||||
override predicate mayBeImpure() { none() }
|
||||
@@ -794,11 +773,6 @@ class AlignofExprOperator extends AlignofOperator {
|
||||
*/
|
||||
Expr getExprOperand() { result = this.getChild(0) }
|
||||
|
||||
/**
|
||||
* DEPRECATED: Use `getExprOperand()` instead.
|
||||
*/
|
||||
deprecated Expr getExpr() { result = this.getExprOperand() }
|
||||
|
||||
override string toString() { result = "alignof(<expr>)" }
|
||||
}
|
||||
|
||||
@@ -814,11 +788,6 @@ class AlignofTypeOperator extends AlignofOperator {
|
||||
/** Gets the contained type. */
|
||||
Type getTypeOperand() { sizeof_bind(underlyingElement(this), unresolveElement(result)) }
|
||||
|
||||
/**
|
||||
* DEPRECATED: Use `getTypeOperand()` instead.
|
||||
*/
|
||||
deprecated Type getSpecifiedType() { result = this.getTypeOperand() }
|
||||
|
||||
override string toString() { result = "alignof(" + this.getTypeOperand().getName() + ")" }
|
||||
}
|
||||
|
||||
|
||||
@@ -48,16 +48,6 @@ class NEExpr extends EqualityOperation, @neexpr {
|
||||
class RelationalOperation extends ComparisonOperation, @rel_op_expr {
|
||||
override int getPrecedence() { result = 10 }
|
||||
|
||||
/**
|
||||
* DEPRECATED: Use `getGreaterOperand()` instead.
|
||||
*/
|
||||
deprecated Expr getLarge() { result = getGreaterOperand() }
|
||||
|
||||
/**
|
||||
* DEPRECATED: Use `getLesserOperand()` instead.
|
||||
*/
|
||||
deprecated Expr getSmall() { result = getLesserOperand() }
|
||||
|
||||
/**
|
||||
* Gets the operand on the "greater" (or "greater-or-equal") side
|
||||
* of this relational expression, that is, the side that is larger
|
||||
|
||||
@@ -114,13 +114,6 @@ class Expr extends StmtParent, @expr {
|
||||
*/
|
||||
Type getUnspecifiedType() { result = this.getType().getUnspecifiedType() }
|
||||
|
||||
/**
|
||||
* Gets an integer indicating the type of expression that this represents.
|
||||
*
|
||||
* DEPRECATED: use the subclasses of `Expr` rather than relying on this predicate.
|
||||
*/
|
||||
deprecated int getKind() { exprs(underlyingElement(this), result, _) }
|
||||
|
||||
/** Gets a textual representation of this expression. */
|
||||
override string toString() { none() }
|
||||
|
||||
|
||||
@@ -164,16 +164,6 @@ class HexLiteral extends Literal {
|
||||
class AggregateLiteral extends Expr, @aggregateliteral {
|
||||
override string getAPrimaryQlClass() { result = "AggregateLiteral" }
|
||||
|
||||
/**
|
||||
* DEPRECATED: Use ClassAggregateLiteral.getFieldExpr() instead.
|
||||
*
|
||||
* Gets the expression within the aggregate literal that is used to initialise field `f`,
|
||||
* if this literal is being used to initialise a class/struct instance.
|
||||
*/
|
||||
deprecated Expr getCorrespondingExpr(Field f) {
|
||||
result = this.(ClassAggregateLiteral).getFieldExpr(f)
|
||||
}
|
||||
|
||||
override predicate mayBeImpure() { this.getAChild().mayBeImpure() }
|
||||
|
||||
override predicate mayBeGloballyImpure() { this.getAChild().mayBeGloballyImpure() }
|
||||
|
||||
@@ -1,297 +0,0 @@
|
||||
/**
|
||||
* DEPRECATED: Objective-C is no longer supported.
|
||||
*/
|
||||
|
||||
import semmle.code.cpp.exprs.Expr
|
||||
import semmle.code.cpp.Class
|
||||
import semmle.code.cpp.ObjectiveC
|
||||
private import semmle.code.cpp.internal.ResolveClass
|
||||
|
||||
/**
|
||||
* DEPRECATED: Objective-C is no longer supported.
|
||||
* An Objective C message expression, for example `[myColor changeColorToRed:5.0 green:2.0 blue:6.0]`.
|
||||
*/
|
||||
deprecated class MessageExpr extends Expr, Call {
|
||||
MessageExpr() { none() }
|
||||
|
||||
override string toString() { none() }
|
||||
|
||||
/**
|
||||
* Gets the selector of this message expression, for example `-changeColorToRed:green:blue:`.
|
||||
*/
|
||||
string getSelector() { none() }
|
||||
|
||||
/**
|
||||
* Gets the function invoked by this message expression, as inferred by the compiler.
|
||||
*
|
||||
* If the compiler could infer the type of the receiver, and that type had a method
|
||||
* whose name matched the selector, then the result of this predicate is said method.
|
||||
* Otherwise this predicate has no result.
|
||||
*
|
||||
* In all cases, actual function dispatch isn't performed until runtime, but the
|
||||
* lack of a static target is often cause for concern.
|
||||
*/
|
||||
MemberFunction getStaticTarget() { none() }
|
||||
|
||||
/**
|
||||
* Provided for compatibility with Call. It is the same as the static target.
|
||||
*/
|
||||
override MemberFunction getTarget() { none() }
|
||||
|
||||
/**
|
||||
* Holds if the compiler could infer a function as the target of this message.
|
||||
*
|
||||
* In all cases, actual function dispatch isn't performed until runtime, but the
|
||||
* lack of a static target is often cause for concern.
|
||||
*/
|
||||
predicate hasStaticTarget() { none() }
|
||||
|
||||
/**
|
||||
* Gets the number of arguments passed by this message expression.
|
||||
*
|
||||
* In most cases, this equals the number of colons in the selector, but this needn't be the
|
||||
* case for variadic methods like "-initWithFormat:", which can have more than one argument.
|
||||
*/
|
||||
override int getNumberOfArguments() { none() }
|
||||
|
||||
/**
|
||||
* Gets an argument passed by this message expression.
|
||||
*/
|
||||
override Expr getAnArgument() { none() }
|
||||
|
||||
/**
|
||||
* Gets the nth argument passed by this message expression.
|
||||
*
|
||||
* The range of `n` is [`0` .. `getNumberOfArguments()`].
|
||||
*/
|
||||
override Expr getArgument(int n) { none() }
|
||||
|
||||
override int getPrecedence() { none() }
|
||||
}
|
||||
|
||||
/**
|
||||
* DEPRECATED: Objective-C is no longer supported.
|
||||
* An Objective C message expression whose receiver is `super`, for example `[super init]`.
|
||||
*/
|
||||
deprecated class SuperMessageExpr extends MessageExpr {
|
||||
SuperMessageExpr() { none() }
|
||||
}
|
||||
|
||||
/**
|
||||
* DEPRECATED: Objective-C is no longer supported.
|
||||
* An Objective C message expression whose receiver is the name of a class, and
|
||||
* is therefore calling a class method rather than an instance method. This occurs
|
||||
* most commonly for the "+alloc", "+new", and "+class" selectors.
|
||||
*/
|
||||
deprecated class ClassMessageExpr extends MessageExpr {
|
||||
ClassMessageExpr() { none() }
|
||||
|
||||
/**
|
||||
* Gets the class which is the receiver of this message.
|
||||
*/
|
||||
Type getReceiver() { none() }
|
||||
}
|
||||
|
||||
/**
|
||||
* DEPRECATED: Objective-C is no longer supported.
|
||||
* An Objective C message expression whose receiver is an expression (which includes the
|
||||
* common case of the receiver being "self").
|
||||
*/
|
||||
deprecated class ExprMessageExpr extends MessageExpr {
|
||||
ExprMessageExpr() { none() }
|
||||
|
||||
/**
|
||||
* Gets the expression which gives the receiver of this message.
|
||||
*/
|
||||
Expr getReceiver() { none() }
|
||||
|
||||
/**
|
||||
* Gets the Objective C class of which the receiving expression is an instance.
|
||||
*
|
||||
* If the receiving expression has type `id` or type `id<P>` for some protocol `P`,
|
||||
* then there will be no result. If the receiving expression has type `C*` or type
|
||||
* `C<P>*` for some protocol `P`, then the result will be the type `C`.
|
||||
*/
|
||||
ObjectiveClass getReceiverClass() { none() }
|
||||
|
||||
/**
|
||||
* Gets the Objective C classes and/or protocols which are statically implemented
|
||||
* by the receiving expression.
|
||||
*
|
||||
* If the receiving expression has type `id`, then there will be no result.
|
||||
* If the receiving expression has type `id<P>`, then `P` will be the sole result.
|
||||
* If the receiving expression has type `C*`, then `C` will be the sole result.
|
||||
* If the receiving expression has type `C<P>*`, then `C` and `P` will both be results.
|
||||
*/
|
||||
Class getAReceiverClassOrProtocol() { none() }
|
||||
}
|
||||
|
||||
/**
|
||||
* DEPRECATED: Objective-C is no longer supported.
|
||||
* An access to an Objective C property using dot syntax.
|
||||
*
|
||||
* Such accesses are de-sugared into a message expression to the property's getter or setter.
|
||||
*/
|
||||
deprecated class PropertyAccess extends ExprMessageExpr {
|
||||
PropertyAccess() { none() }
|
||||
|
||||
/**
|
||||
* Gets the property being accessed by this expression.
|
||||
*/
|
||||
Property getProperty() { none() }
|
||||
}
|
||||
|
||||
/**
|
||||
* DEPRECATED: Objective-C is no longer supported.
|
||||
* An Objective C `@selector` expression, for example `@selector(driveForDistance:)`.
|
||||
*/
|
||||
deprecated class AtSelectorExpr extends Expr {
|
||||
AtSelectorExpr() { none() }
|
||||
|
||||
override string toString() { none() }
|
||||
|
||||
/**
|
||||
* Gets the selector of this `@selector` expression, for example `driveForDistance:`.
|
||||
*/
|
||||
string getSelector() { none() }
|
||||
}
|
||||
|
||||
/**
|
||||
* DEPRECATED: Objective-C is no longer supported.
|
||||
* An Objective C `@protocol` expression, for example `@protocol(SomeProtocol)`.
|
||||
*/
|
||||
deprecated class AtProtocolExpr extends Expr {
|
||||
AtProtocolExpr() { none() }
|
||||
|
||||
override string toString() { none() }
|
||||
|
||||
/**
|
||||
* Gets the protocol of this `@protocol` expression, for example `SomeProtocol`.
|
||||
*/
|
||||
Protocol getProtocol() { none() }
|
||||
}
|
||||
|
||||
/**
|
||||
* DEPRECATED: Objective-C is no longer supported.
|
||||
* An Objective C `@encode` expression, for example `@encode(int *)`.
|
||||
*/
|
||||
deprecated class AtEncodeExpr extends Expr {
|
||||
AtEncodeExpr() { none() }
|
||||
|
||||
override string toString() { none() }
|
||||
|
||||
/**
|
||||
* Gets the type this `@encode` expression encodes, for example `int *`.
|
||||
*/
|
||||
Type getEncodedType() { none() }
|
||||
}
|
||||
|
||||
/**
|
||||
* DEPRECATED: Objective-C is no longer supported.
|
||||
* An Objective C throw expression.
|
||||
*/
|
||||
deprecated class ObjcThrowExpr extends ThrowExpr {
|
||||
ObjcThrowExpr() { none() }
|
||||
|
||||
override string toString() { none() }
|
||||
}
|
||||
|
||||
/**
|
||||
* DEPRECATED: Objective-C is no longer supported.
|
||||
* An Objective C throw expression with no argument (which causes the
|
||||
* current exception to be re-thrown).
|
||||
*/
|
||||
deprecated class ObjcReThrowExpr extends ReThrowExpr, ObjcThrowExpr {
|
||||
ObjcReThrowExpr() { none() }
|
||||
|
||||
override string toString() { none() }
|
||||
}
|
||||
|
||||
/**
|
||||
* DEPRECATED: Objective-C is no longer supported.
|
||||
* An Objective C @ expression which boxes a single value, such as @(22).
|
||||
*/
|
||||
deprecated class AtExpr extends UnaryOperation {
|
||||
AtExpr() { none() }
|
||||
|
||||
override string toString() { none() }
|
||||
|
||||
override string getOperator() { none() }
|
||||
}
|
||||
|
||||
/**
|
||||
* DEPRECATED: Objective-C is no longer supported.
|
||||
* An Objective C @[...] literal.
|
||||
*/
|
||||
deprecated class ArrayLiteral extends Expr {
|
||||
ArrayLiteral() { none() }
|
||||
|
||||
/** Gets a textual representation of this array literal. */
|
||||
override string toString() { none() }
|
||||
|
||||
/** An element of the array */
|
||||
Expr getElement(int i) { none() }
|
||||
}
|
||||
|
||||
/**
|
||||
* DEPRECATED: Objective-C is no longer supported.
|
||||
* An Objective C @{...} literal.
|
||||
*/
|
||||
deprecated class DictionaryLiteral extends Expr {
|
||||
DictionaryLiteral() { none() }
|
||||
|
||||
/** Gets a textual representation of this dictionary literal. */
|
||||
override string toString() { none() }
|
||||
}
|
||||
|
||||
/**
|
||||
* DEPRECATED: Objective-C is no longer supported.
|
||||
* An Objective C @"..." string literal.
|
||||
*/
|
||||
deprecated class ObjCLiteralString extends TextLiteral {
|
||||
ObjCLiteralString() { none() }
|
||||
}
|
||||
|
||||
/**
|
||||
* DEPRECATED: Objective-C is no longer supported.
|
||||
* An Objective C/C++ overloaded subscripting access expression.
|
||||
*
|
||||
* Either
|
||||
* obj[idx]
|
||||
* or
|
||||
* obj[idx] = expr
|
||||
*/
|
||||
deprecated class SubscriptExpr extends Expr {
|
||||
SubscriptExpr() { none() }
|
||||
|
||||
/**
|
||||
* Gets the object expression being subscripted.
|
||||
*/
|
||||
Expr getSubscriptBase() { none() }
|
||||
|
||||
/**
|
||||
* Gets the expression giving the index into the object.
|
||||
*/
|
||||
Expr getSubscriptIndex() { none() }
|
||||
|
||||
/**
|
||||
* Gets the expression being assigned (if this is an assignment).
|
||||
*/
|
||||
Expr getAssignedExpr() { none() }
|
||||
|
||||
override string toString() { none() }
|
||||
}
|
||||
|
||||
/**
|
||||
* DEPRECATED: Objective-C is no longer supported.
|
||||
* An Objective C _cmd expression.
|
||||
*/
|
||||
deprecated class CmdExpr extends Expr {
|
||||
CmdExpr() { none() }
|
||||
|
||||
override string toString() { none() }
|
||||
|
||||
override predicate mayBeImpure() { none() }
|
||||
|
||||
override predicate mayBeGloballyImpure() { none() }
|
||||
}
|
||||
@@ -39,19 +39,6 @@ class CorrectIncludeGuard extends IncludeGuardedHeader {
|
||||
PreprocessorEndif getEndif() { correctIncludeGuard(this, _, _, result, _) }
|
||||
}
|
||||
|
||||
/**
|
||||
* DEPRECATED: no longer useful.
|
||||
*/
|
||||
deprecated class NotIncludedGuard extends IncludeGuardedHeader {
|
||||
NotIncludedGuard() { none() }
|
||||
|
||||
/** Gets the `#ifndef` directive used to prevent multiple inclusion of this file. */
|
||||
PreprocessorIfndef getIfndef() { result.getFile() = this }
|
||||
|
||||
/** Gets the `#endif` directive closing this file. */
|
||||
PreprocessorEndif getEndif() { result.getFile() = this }
|
||||
}
|
||||
|
||||
/**
|
||||
* A file with no code in it.
|
||||
*/
|
||||
|
||||
@@ -21,9 +21,4 @@ import semmle.code.cpp.ir.dataflow.DataFlow2
|
||||
module TaintTracking {
|
||||
import semmle.code.cpp.ir.dataflow.internal.tainttracking1.TaintTrackingImpl
|
||||
private import semmle.code.cpp.ir.dataflow.TaintTracking2
|
||||
|
||||
/**
|
||||
* DEPRECATED: Use TaintTracking2::Configuration instead.
|
||||
*/
|
||||
deprecated class Configuration2 = TaintTracking2::Configuration;
|
||||
}
|
||||
|
||||
@@ -158,14 +158,6 @@ class Node extends TIRDataFlowNode {
|
||||
*/
|
||||
Expr asPartialDefinition() { result = this.(PartialDefinitionNode).getDefinedExpr() }
|
||||
|
||||
/**
|
||||
* DEPRECATED: See UninitializedNode.
|
||||
*
|
||||
* Gets the uninitialized local variable corresponding to this node, if
|
||||
* any.
|
||||
*/
|
||||
deprecated LocalVariable asUninitialized() { none() }
|
||||
|
||||
/**
|
||||
* Gets an upper bound on the type of this node.
|
||||
*/
|
||||
@@ -560,22 +552,6 @@ class ParameterIndirectionNode extends ParameterNode {
|
||||
override string toString() { result = "*" + instr.getIRVariable().toString() }
|
||||
}
|
||||
|
||||
/**
|
||||
* DEPRECATED: Data flow was never an accurate way to determine what
|
||||
* expressions might be uninitialized. It errs on the side of saying that
|
||||
* everything is uninitialized, and this is even worse in the IR because the IR
|
||||
* doesn't use syntactic hints to rule out variables that are definitely
|
||||
* initialized.
|
||||
*
|
||||
* The value of an uninitialized local variable, viewed as a node in a data
|
||||
* flow graph.
|
||||
*/
|
||||
deprecated class UninitializedNode extends Node {
|
||||
UninitializedNode() { none() }
|
||||
|
||||
LocalVariable getLocalVariable() { none() }
|
||||
}
|
||||
|
||||
/**
|
||||
* A node associated with an object after an operation that might have
|
||||
* changed its state.
|
||||
@@ -725,14 +701,6 @@ InstructionNode instructionNode(Instruction instr) { result.getInstruction() = i
|
||||
*/
|
||||
OperandNode operandNode(Operand operand) { result.getOperand() = operand }
|
||||
|
||||
/**
|
||||
* DEPRECATED: use `definitionByReferenceNodeFromArgument` instead.
|
||||
*
|
||||
* Gets the `Node` corresponding to a definition by reference of the variable
|
||||
* that is passed as `argument` of a call.
|
||||
*/
|
||||
deprecated DefinitionByReferenceNode definitionByReferenceNode(Expr e) { result.getArgument() = e }
|
||||
|
||||
/**
|
||||
* Gets the `Node` corresponding to the value of evaluating `e` or any of its
|
||||
* conversions. There is no result if `e` is a `Conversion`. For data flowing
|
||||
|
||||
@@ -23,8 +23,6 @@ private class Printf extends FormattingFunction, AliasFunction {
|
||||
|
||||
override int getFormatParameterIndex() { result = 0 }
|
||||
|
||||
deprecated override predicate isWideCharDefault() { hasName(["wprintf", "wprintf_s"]) }
|
||||
|
||||
override predicate isOutputGlobal() { any() }
|
||||
|
||||
override predicate parameterNeverEscapes(int n) { n = 0 }
|
||||
@@ -49,8 +47,6 @@ private class Fprintf extends FormattingFunction {
|
||||
|
||||
override int getFormatParameterIndex() { result = 1 }
|
||||
|
||||
deprecated override predicate isWideCharDefault() { hasName("fwprintf") }
|
||||
|
||||
override int getOutputParameterIndex(boolean isStream) { result = 0 and isStream = true }
|
||||
}
|
||||
|
||||
@@ -77,15 +73,6 @@ private class Sprintf extends FormattingFunction {
|
||||
not exists(getDefinition().getFile().getRelativePath())
|
||||
}
|
||||
|
||||
deprecated override predicate isWideCharDefault() {
|
||||
getParameter(getFormatParameterIndex())
|
||||
.getType()
|
||||
.getUnspecifiedType()
|
||||
.(PointerType)
|
||||
.getBaseType()
|
||||
.getSize() > 1
|
||||
}
|
||||
|
||||
override int getFormatParameterIndex() {
|
||||
hasName("g_strdup_printf") and result = 0
|
||||
or
|
||||
@@ -133,15 +120,6 @@ private class SnprintfImpl extends Snprintf {
|
||||
else result = getFirstFormatArgumentIndex() - 1
|
||||
}
|
||||
|
||||
deprecated override predicate isWideCharDefault() {
|
||||
getParameter(getFormatParameterIndex())
|
||||
.getType()
|
||||
.getUnspecifiedType()
|
||||
.(PointerType)
|
||||
.getBaseType()
|
||||
.getSize() > 1
|
||||
}
|
||||
|
||||
override int getOutputParameterIndex(boolean isStream) { result = 0 and isStream = false }
|
||||
|
||||
override int getFirstFormatArgumentIndex() {
|
||||
@@ -182,15 +160,6 @@ private class StringCchPrintf extends FormattingFunction {
|
||||
if getName().matches("%Ex") then result = 5 else result = 2
|
||||
}
|
||||
|
||||
deprecated override predicate isWideCharDefault() {
|
||||
getParameter(getFormatParameterIndex())
|
||||
.getType()
|
||||
.getUnspecifiedType()
|
||||
.(PointerType)
|
||||
.getBaseType()
|
||||
.getSize() > 1
|
||||
}
|
||||
|
||||
override int getOutputParameterIndex(boolean isStream) { result = 0 and isStream = false }
|
||||
|
||||
override int getSizeParameterIndex() { result = 1 }
|
||||
|
||||
@@ -52,14 +52,6 @@ abstract class FormattingFunction extends ArrayFunction, TaintFunction {
|
||||
*/
|
||||
predicate isMicrosoft() { anyFileCompiledAsMicrosoft() }
|
||||
|
||||
/**
|
||||
* Holds if the default meaning of `%s` is a `wchar_t *`, rather than
|
||||
* a `char *` (either way, `%S` will have the opposite meaning).
|
||||
*
|
||||
* DEPRECATED: Use getDefaultCharType() instead.
|
||||
*/
|
||||
deprecated predicate isWideCharDefault() { none() }
|
||||
|
||||
/**
|
||||
* Gets the character type used in the format string for this function.
|
||||
*/
|
||||
@@ -116,13 +108,6 @@ abstract class FormattingFunction extends ArrayFunction, TaintFunction {
|
||||
*/
|
||||
int getOutputParameterIndex(boolean isStream) { none() }
|
||||
|
||||
/**
|
||||
* Gets the position at which the output parameter, if any, occurs.
|
||||
*
|
||||
* DEPRECATED: use `getOutputParameterIndex(boolean isStream)` instead.
|
||||
*/
|
||||
deprecated int getOutputParameterIndex() { result = getOutputParameterIndex(_) }
|
||||
|
||||
/**
|
||||
* Holds if this function outputs to a global stream such as standard output,
|
||||
* standard error or a system log. For example `printf`.
|
||||
|
||||
@@ -705,24 +705,6 @@ private float getTruncatedUpperBounds(Expr expr) {
|
||||
result = exprMaxVal(expr)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if the expression might overflow negatively. This predicate
|
||||
* does not consider the possibility that the expression might overflow
|
||||
* due to a conversion.
|
||||
*
|
||||
* DEPRECATED: use `exprMightOverflowNegatively` instead.
|
||||
*/
|
||||
deprecated predicate negative_overflow(Expr expr) { exprMightOverflowNegatively(expr) }
|
||||
|
||||
/**
|
||||
* Holds if the expression might overflow positively. This predicate
|
||||
* does not consider the possibility that the expression might overflow
|
||||
* due to a conversion.
|
||||
*
|
||||
* DEPRECATED: use `exprMightOverflowPositively` instead.
|
||||
*/
|
||||
deprecated predicate positive_overflow(Expr expr) { exprMightOverflowPositively(expr) }
|
||||
|
||||
/** Only to be called by `getTruncatedLowerBounds`. */
|
||||
private float getLowerBoundsImpl(Expr expr) {
|
||||
(
|
||||
|
||||
@@ -84,31 +84,3 @@ string getSecureAlgorithmRegex() {
|
||||
"(^|.*[A-Z]{2}|.*[^a-zA-Z0-9])(" + strictconcat(getASecureAlgorithmName().toLowerCase(), "|") +
|
||||
")([^a-z0-9].*|$)"
|
||||
}
|
||||
|
||||
/**
|
||||
* DEPRECATED: Terminology has been updated. Use `getAnInsecureAlgorithmName()`
|
||||
* instead.
|
||||
*/
|
||||
deprecated string algorithmBlacklist() { result = getAnInsecureAlgorithmName() }
|
||||
|
||||
/**
|
||||
* DEPRECATED: Terminology has been updated. Use
|
||||
* `getAnInsecureHashAlgorithmName()` instead.
|
||||
*/
|
||||
deprecated string hashAlgorithmBlacklist() { result = getAnInsecureHashAlgorithmName() }
|
||||
|
||||
/**
|
||||
* DEPRECATED: Terminology has been updated. Use `getInsecureAlgorithmRegex()` instead.
|
||||
*/
|
||||
deprecated string algorithmBlacklistRegex() { result = getInsecureAlgorithmRegex() }
|
||||
|
||||
/**
|
||||
* DEPRECATED: Terminology has been updated. Use `getASecureAlgorithmName()`
|
||||
* instead.
|
||||
*/
|
||||
deprecated string algorithmWhitelist() { result = getASecureAlgorithmName() }
|
||||
|
||||
/**
|
||||
* DEPRECATED: Terminology has been updated. Use `getSecureAlgorithmRegex()` instead.
|
||||
*/
|
||||
deprecated string algorithmWhitelistRegex() { result = getSecureAlgorithmRegex() }
|
||||
|
||||
@@ -126,9 +126,3 @@ class BlockStmt extends Stmt, @stmt_block {
|
||||
|
||||
override predicate mayBeGloballyImpure() { this.getAStmt().mayBeGloballyImpure() }
|
||||
}
|
||||
|
||||
/**
|
||||
* DEPRECATED: This is now called `BlockStmt` to avoid confusion with
|
||||
* `BasicBlock`.
|
||||
*/
|
||||
deprecated class Block = BlockStmt;
|
||||
|
||||
@@ -61,13 +61,6 @@ class Stmt extends StmtParent, @stmt {
|
||||
|
||||
override Location getLocation() { stmts(underlyingElement(this), _, result) }
|
||||
|
||||
/**
|
||||
* Gets an int indicating the type of statement that this represents.
|
||||
*
|
||||
* DEPRECATED: use the subclasses of `Stmt` rather than relying on this predicate.
|
||||
*/
|
||||
deprecated int getKind() { stmts(underlyingElement(this), result, _) }
|
||||
|
||||
override string toString() { none() }
|
||||
|
||||
override Function getControlFlowScope() { result = this.getEnclosingFunction() }
|
||||
@@ -1230,38 +1223,6 @@ class SwitchCase extends Stmt, @stmt_switch_case {
|
||||
*/
|
||||
int getChildNum() { switch_case(_, result, underlyingElement(this)) }
|
||||
|
||||
/**
|
||||
* DEPRECATED: use `SwitchCase.getAStmt` or `ControlFlowNode.getASuccessor`
|
||||
* rather than this predicate.
|
||||
*
|
||||
* Gets the `BlockStmt` statement immediately following this 'switch case'
|
||||
* statement, if any.
|
||||
*
|
||||
* For example, for
|
||||
* ```
|
||||
* switch (i) {
|
||||
* case 5:
|
||||
* x = 1;
|
||||
* break;
|
||||
* case 6:
|
||||
* case 7:
|
||||
* { x = 2; break; }
|
||||
* default:
|
||||
* { x = 3; }
|
||||
* x = 4;
|
||||
* break;
|
||||
* }
|
||||
* ```
|
||||
* the `case 7:` has result `{ x = 2; break; }`, `default:` has result
|
||||
* `{ x = 3; }`, and the others have no result.
|
||||
*/
|
||||
deprecated BlockStmt getLabelledStmt() {
|
||||
exists(int i, Stmt parent |
|
||||
this = parent.getChild(i) and
|
||||
result = parent.getChild(i + 1)
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the next `SwitchCase` belonging to the same 'switch'
|
||||
* statement, if any.
|
||||
@@ -1741,23 +1702,6 @@ class Handler extends Stmt, @stmt_handler {
|
||||
override predicate mayBeGloballyImpure() { none() }
|
||||
}
|
||||
|
||||
/**
|
||||
* DEPRECATED: Objective-C is no longer supported.
|
||||
* The end of a 'finally' clause.
|
||||
*
|
||||
* This has no concrete representation in the source, but makes the
|
||||
* control flow graph easier to use.
|
||||
*/
|
||||
deprecated class FinallyEnd extends Stmt {
|
||||
FinallyEnd() { none() }
|
||||
|
||||
override string toString() { result = "<finally end>" }
|
||||
|
||||
override predicate mayBeImpure() { none() }
|
||||
|
||||
override predicate mayBeGloballyImpure() { none() }
|
||||
}
|
||||
|
||||
/**
|
||||
* A C/C++ 'try' statement.
|
||||
*
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
* @kind path-problem
|
||||
* @problem.severity warning
|
||||
* @security-severity 6.5
|
||||
* @precision medium
|
||||
* @precision high
|
||||
* @id cpp/system-data-exposure
|
||||
* @tags security
|
||||
* external/cwe/cwe-497
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
---
|
||||
category: minorAnalysis
|
||||
---
|
||||
* The `cpp/system-data-exposure` query has been increased from `medium` to `high` precision, following a number of improvements to the query logic.
|
||||
@@ -128,7 +128,7 @@ ConstructorCall.cpp:
|
||||
# 1| <params>:
|
||||
#-----| getParameter(0): [Parameter] (unnamed parameter 0)
|
||||
#-----| Type = [RValueReferenceType] C &&
|
||||
# 3| [ConversionConstructor] void C::C(int)
|
||||
# 3| [Constructor] void C::C(int)
|
||||
# 3| <params>:
|
||||
# 3| getParameter(0): [Parameter] i
|
||||
# 3| Type = [IntType] int
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import cpp
|
||||
import semmle.code.cpp.exprs.ObjectiveC
|
||||
|
||||
string arguments(Function f, int i) {
|
||||
result = "," and i = -1
|
||||
|
||||
@@ -5401,7 +5401,7 @@ ir.cpp:
|
||||
# 600| <params>:
|
||||
# 600| getParameter(0): [Parameter] (unnamed parameter 0)
|
||||
# 600| Type = [RValueReferenceType] String &&
|
||||
# 601| [ConversionConstructor] void String::String(char const*)
|
||||
# 601| [Constructor] void String::String(char const*)
|
||||
# 601| <params>:
|
||||
# 601| getParameter(0): [Parameter] (unnamed parameter 0)
|
||||
# 601| Type = [PointerType] const char *
|
||||
@@ -10630,7 +10630,7 @@ ir.cpp:
|
||||
# 1330| <params>:
|
||||
#-----| getParameter(0): [Parameter] (unnamed parameter 0)
|
||||
#-----| Type = [RValueReferenceType] constructor_only &&
|
||||
# 1335| [ConversionConstructor] void constructor_only::constructor_only(int)
|
||||
# 1335| [Constructor] void constructor_only::constructor_only(int)
|
||||
# 1335| <params>:
|
||||
# 1335| getParameter(0): [Parameter] x
|
||||
# 1335| Type = [IntType] int
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import cpp
|
||||
import semmle.code.cpp.exprs.ObjectiveC
|
||||
|
||||
from ControlFlowNode x, ControlFlowNode y, string entryPoint
|
||||
where
|
||||
|
||||
@@ -30,7 +30,6 @@
|
||||
| variables.cpp:15:12:15:13 | v1 | file://:0:0:0:0 | int[10] | StaticStorageDurationVariable | | static |
|
||||
| variables.cpp:15:21:15:22 | pv | file://:0:0:0:0 | int * | GlobalVariable | | static |
|
||||
| variables.cpp:15:21:15:22 | pv | file://:0:0:0:0 | int * | StaticStorageDurationVariable | | static |
|
||||
| variables.cpp:17:7:17:8 | fp | file://:0:0:0:0 | ..(*)(..) | FunctionPointerVariable | | |
|
||||
| variables.cpp:17:7:17:8 | fp | file://:0:0:0:0 | ..(*)(..) | GlobalVariable | | |
|
||||
| variables.cpp:17:7:17:8 | fp | file://:0:0:0:0 | ..(*)(..) | StaticStorageDurationVariable | | |
|
||||
| variables.cpp:19:7:19:8 | v2 | file://:0:0:0:0 | float[3] | GlobalVariable | | |
|
||||
|
||||
@@ -51,7 +51,7 @@ namespace Semmle.Autobuild.CSharp.Tests
|
||||
|
||||
int IBuildActions.RunProcess(string cmd, string args, string? workingDirectory, IDictionary<string, string>? env, out IList<string> stdOut)
|
||||
{
|
||||
var pattern = cmd + " " + args;
|
||||
var pattern = string.IsNullOrEmpty(args) ? cmd : cmd + " " + args;
|
||||
RunProcessIn.Add(pattern);
|
||||
|
||||
if (!RunProcessOut.TryGetValue(pattern, out var str))
|
||||
@@ -62,7 +62,7 @@ namespace Semmle.Autobuild.CSharp.Tests
|
||||
RunProcessWorkingDirectory.TryGetValue(pattern, out var wd);
|
||||
|
||||
if (wd != workingDirectory)
|
||||
throw new ArgumentException("Missing RunProcessWorkingDirectory " + pattern);
|
||||
throw new ArgumentException($"Unexpected RunProcessWorkingDirectory, got {wd ?? "null"} expected {workingDirectory ?? "null"} in {pattern}");
|
||||
|
||||
if (!RunProcess.TryGetValue(pattern, out var ret))
|
||||
throw new ArgumentException("Missing RunProcess " + pattern);
|
||||
@@ -72,12 +72,12 @@ namespace Semmle.Autobuild.CSharp.Tests
|
||||
|
||||
int IBuildActions.RunProcess(string cmd, string args, string? workingDirectory, IDictionary<string, string>? env)
|
||||
{
|
||||
var pattern = cmd + " " + args;
|
||||
var pattern = string.IsNullOrEmpty(args) ? cmd : cmd + " " + args;
|
||||
RunProcessIn.Add(pattern);
|
||||
RunProcessWorkingDirectory.TryGetValue(pattern, out var wd);
|
||||
|
||||
if (wd != workingDirectory)
|
||||
throw new ArgumentException("Missing RunProcessWorkingDirectory " + pattern);
|
||||
throw new ArgumentException($"Unexpected RunProcessWorkingDirectory, got {wd ?? "null"} expected {workingDirectory ?? "null"} in {pattern}");
|
||||
|
||||
if (!RunProcess.TryGetValue(pattern, out var ret))
|
||||
throw new ArgumentException("Missing RunProcess " + pattern);
|
||||
@@ -255,7 +255,7 @@ namespace Semmle.Autobuild.CSharp.Tests
|
||||
[Fact]
|
||||
public void TestAnd1()
|
||||
{
|
||||
var cmd = BuildScript.Create("abc", "def ghi", false, null, null) & BuildScript.Create("odasa", null, false, null, null);
|
||||
var cmd = BuildScript.Create("abc", "def ghi", false, null, null) & BuildScript.Create("codeql", null, false, null, null);
|
||||
|
||||
actions.RunProcess["abc def ghi"] = 1;
|
||||
cmd.Run(actions, StartCallback, EndCallback);
|
||||
@@ -269,14 +269,14 @@ namespace Semmle.Autobuild.CSharp.Tests
|
||||
[Fact]
|
||||
public void TestAnd2()
|
||||
{
|
||||
var cmd = BuildScript.Create("odasa", null, false, null, null) & BuildScript.Create("abc", "def ghi", false, null, null);
|
||||
var cmd = BuildScript.Create("codeql", null, false, null, null) & BuildScript.Create("abc", "def ghi", false, null, null);
|
||||
|
||||
actions.RunProcess["abc def ghi"] = 1;
|
||||
actions.RunProcess["odasa "] = 0;
|
||||
actions.RunProcess["codeql"] = 0;
|
||||
cmd.Run(actions, StartCallback, EndCallback);
|
||||
|
||||
Assert.Equal("odasa ", actions.RunProcessIn[0]);
|
||||
Assert.Equal("odasa ", startCallbackIn[0]);
|
||||
Assert.Equal("codeql", actions.RunProcessIn[0]);
|
||||
Assert.Equal("codeql", startCallbackIn[0]);
|
||||
Assert.Equal("", endCallbackIn[0]);
|
||||
Assert.Equal(0, endCallbackReturn[0]);
|
||||
|
||||
@@ -289,14 +289,14 @@ namespace Semmle.Autobuild.CSharp.Tests
|
||||
[Fact]
|
||||
public void TestOr1()
|
||||
{
|
||||
var cmd = BuildScript.Create("odasa", null, false, null, null) | BuildScript.Create("abc", "def ghi", false, null, null);
|
||||
var cmd = BuildScript.Create("codeql", null, false, null, null) | BuildScript.Create("abc", "def ghi", false, null, null);
|
||||
|
||||
actions.RunProcess["abc def ghi"] = 1;
|
||||
actions.RunProcess["odasa "] = 0;
|
||||
actions.RunProcess["codeql"] = 0;
|
||||
cmd.Run(actions, StartCallback, EndCallback);
|
||||
|
||||
Assert.Equal("odasa ", actions.RunProcessIn[0]);
|
||||
Assert.Equal("odasa ", startCallbackIn[0]);
|
||||
Assert.Equal("codeql", actions.RunProcessIn[0]);
|
||||
Assert.Equal("codeql", startCallbackIn[0]);
|
||||
Assert.Equal("", endCallbackIn[0]);
|
||||
Assert.Equal(0, endCallbackReturn[0]);
|
||||
Assert.Equal(1, endCallbackReturn.Count);
|
||||
@@ -305,10 +305,10 @@ namespace Semmle.Autobuild.CSharp.Tests
|
||||
[Fact]
|
||||
public void TestOr2()
|
||||
{
|
||||
var cmd = BuildScript.Create("abc", "def ghi", false, null, null) | BuildScript.Create("odasa", null, false, null, null);
|
||||
var cmd = BuildScript.Create("abc", "def ghi", false, null, null) | BuildScript.Create("codeql", null, false, null, null);
|
||||
|
||||
actions.RunProcess["abc def ghi"] = 1;
|
||||
actions.RunProcess["odasa "] = 0;
|
||||
actions.RunProcess["codeql"] = 0;
|
||||
cmd.Run(actions, StartCallback, EndCallback);
|
||||
|
||||
Assert.Equal("abc def ghi", actions.RunProcessIn[0]);
|
||||
@@ -316,8 +316,8 @@ namespace Semmle.Autobuild.CSharp.Tests
|
||||
Assert.Equal("", endCallbackIn[0]);
|
||||
Assert.Equal(1, endCallbackReturn[0]);
|
||||
|
||||
Assert.Equal("odasa ", actions.RunProcessIn[1]);
|
||||
Assert.Equal("odasa ", startCallbackIn[1]);
|
||||
Assert.Equal("codeql", actions.RunProcessIn[1]);
|
||||
Assert.Equal("codeql", startCallbackIn[1]);
|
||||
Assert.Equal("", endCallbackIn[1]);
|
||||
Assert.Equal(0, endCallbackReturn[1]);
|
||||
}
|
||||
@@ -385,9 +385,6 @@ namespace Semmle.Autobuild.CSharp.Tests
|
||||
actions.GetEnvironmentVariable[$"CODEQL_EXTRACTOR_{codeqlUpperLanguage}_ROOT"] = $@"C:\codeql\{codeqlUpperLanguage.ToLowerInvariant()}";
|
||||
actions.GetEnvironmentVariable["CODEQL_JAVA_HOME"] = @"C:\codeql\tools\java";
|
||||
actions.GetEnvironmentVariable["CODEQL_PLATFORM"] = isWindows ? "win64" : "linux64";
|
||||
actions.GetEnvironmentVariable["SEMMLE_DIST"] = @"C:\odasa";
|
||||
actions.GetEnvironmentVariable["SEMMLE_JAVA_HOME"] = @"C:\odasa\tools\java";
|
||||
actions.GetEnvironmentVariable["SEMMLE_PLATFORM_TOOLS"] = @"C:\odasa\tools";
|
||||
actions.GetEnvironmentVariable["LGTM_INDEX_VSTOOLS_VERSION"] = vsToolsVersion;
|
||||
actions.GetEnvironmentVariable["LGTM_INDEX_MSBUILD_ARGUMENTS"] = msBuildArguments;
|
||||
actions.GetEnvironmentVariable["LGTM_INDEX_MSBUILD_PLATFORM"] = msBuildPlatform;
|
||||
@@ -416,7 +413,7 @@ namespace Semmle.Autobuild.CSharp.Tests
|
||||
actions.RunProcess["cmd.exe /C dotnet --info"] = 0;
|
||||
actions.RunProcess[@"cmd.exe /C dotnet clean C:\Project\test.csproj"] = 0;
|
||||
actions.RunProcess[@"cmd.exe /C dotnet restore C:\Project\test.csproj"] = 0;
|
||||
actions.RunProcess[@"cmd.exe /C C:\odasa\tools\odasa index --auto dotnet build --no-incremental /p:UseSharedCompilation=false C:\Project\test.csproj"] = 0;
|
||||
actions.RunProcess[@"cmd.exe /C dotnet build --no-incremental /p:UseSharedCompilation=false C:\Project\test.csproj"] = 0;
|
||||
actions.FileExists["csharp.log"] = true;
|
||||
actions.FileExists[@"C:\Project\test.csproj"] = true;
|
||||
actions.GetEnvironmentVariable["CODEQL_EXTRACTOR_CSHARP_TRAP_DIR"] = "";
|
||||
@@ -443,7 +440,7 @@ namespace Semmle.Autobuild.CSharp.Tests
|
||||
actions.RunProcess["dotnet --info"] = 0;
|
||||
actions.RunProcess[@"dotnet clean C:\Project/test.csproj"] = 0;
|
||||
actions.RunProcess[@"dotnet restore C:\Project/test.csproj"] = 0;
|
||||
actions.RunProcess[@"C:\odasa/tools/odasa index --auto dotnet build --no-incremental /p:UseSharedCompilation=false C:\Project/test.csproj"] = 0;
|
||||
actions.RunProcess[@"dotnet build --no-incremental /p:UseSharedCompilation=false C:\Project/test.csproj"] = 0;
|
||||
actions.FileExists["csharp.log"] = true;
|
||||
actions.FileExists[@"C:\Project/test.csproj"] = true;
|
||||
actions.GetEnvironmentVariable["CODEQL_EXTRACTOR_CSHARP_TRAP_DIR"] = "";
|
||||
@@ -601,7 +598,7 @@ namespace Semmle.Autobuild.CSharp.Tests
|
||||
[Fact]
|
||||
public void TestLinuxBuildCommand()
|
||||
{
|
||||
actions.RunProcess[@"C:\odasa/tools/odasa index --auto ""./build.sh --skip-tests"""] = 0;
|
||||
actions.RunProcess["./build.sh --skip-tests"] = 0;
|
||||
actions.FileExists["csharp.log"] = true;
|
||||
actions.GetEnvironmentVariable["CODEQL_EXTRACTOR_CSHARP_TRAP_DIR"] = "";
|
||||
actions.GetEnvironmentVariable["CODEQL_EXTRACTOR_CSHARP_SOURCE_ARCHIVE_DIR"] = "";
|
||||
@@ -622,8 +619,8 @@ namespace Semmle.Autobuild.CSharp.Tests
|
||||
actions.GetEnvironmentVariable["CODEQL_EXTRACTOR_CSHARP_TRAP_DIR"] = "";
|
||||
actions.GetEnvironmentVariable["CODEQL_EXTRACTOR_CSHARP_SOURCE_ARCHIVE_DIR"] = "";
|
||||
actions.RunProcess[@"/bin/chmod u+x C:\Project/build/build.sh"] = 0;
|
||||
actions.RunProcess[@"C:\odasa/tools/odasa index --auto C:\Project/build/build.sh"] = 0;
|
||||
actions.RunProcessWorkingDirectory[@"C:\odasa/tools/odasa index --auto C:\Project/build/build.sh"] = @"C:\Project/build";
|
||||
actions.RunProcess[@"C:\Project/build/build.sh"] = 0;
|
||||
actions.RunProcessWorkingDirectory[@"C:\Project/build/build.sh"] = @"C:\Project/build";
|
||||
actions.FileExists["csharp.log"] = true;
|
||||
|
||||
var autobuilder = CreateAutoBuilder(false);
|
||||
@@ -639,8 +636,8 @@ namespace Semmle.Autobuild.CSharp.Tests
|
||||
actions.GetEnvironmentVariable["CODEQL_EXTRACTOR_CSHARP_SOURCE_ARCHIVE_DIR"] = "";
|
||||
|
||||
actions.RunProcess[@"/bin/chmod u+x C:\Project/build.sh"] = 0;
|
||||
actions.RunProcess[@"C:\odasa/tools/odasa index --auto C:\Project/build.sh"] = 0;
|
||||
actions.RunProcessWorkingDirectory[@"C:\odasa/tools/odasa index --auto C:\Project/build.sh"] = @"C:\Project";
|
||||
actions.RunProcess[@"C:\Project/build.sh"] = 0;
|
||||
actions.RunProcessWorkingDirectory[@"C:\Project/build.sh"] = @"C:\Project";
|
||||
actions.FileExists["csharp.log"] = false;
|
||||
|
||||
var autobuilder = CreateAutoBuilder(false);
|
||||
@@ -656,8 +653,8 @@ namespace Semmle.Autobuild.CSharp.Tests
|
||||
actions.GetEnvironmentVariable["CODEQL_EXTRACTOR_CSHARP_SOURCE_ARCHIVE_DIR"] = "";
|
||||
|
||||
actions.RunProcess[@"/bin/chmod u+x C:\Project/build.sh"] = 0;
|
||||
actions.RunProcess[@"C:\odasa/tools/odasa index --auto C:\Project/build.sh"] = 5;
|
||||
actions.RunProcessWorkingDirectory[@"C:\odasa/tools/odasa index --auto C:\Project/build.sh"] = @"C:\Project";
|
||||
actions.RunProcess[@"C:\Project/build.sh"] = 5;
|
||||
actions.RunProcessWorkingDirectory[@"C:\Project/build.sh"] = @"C:\Project";
|
||||
actions.FileExists["csharp.log"] = true;
|
||||
|
||||
var autobuilder = CreateAutoBuilder(false);
|
||||
@@ -671,8 +668,8 @@ namespace Semmle.Autobuild.CSharp.Tests
|
||||
actions.EnumerateDirectories[@"C:\Project"] = "";
|
||||
actions.GetEnvironmentVariable["CODEQL_EXTRACTOR_CSHARP_TRAP_DIR"] = "";
|
||||
actions.GetEnvironmentVariable["CODEQL_EXTRACTOR_CSHARP_SOURCE_ARCHIVE_DIR"] = "";
|
||||
actions.RunProcess[@"cmd.exe /C C:\odasa\tools\odasa index --auto C:\Project\build.bat"] = 0;
|
||||
actions.RunProcessWorkingDirectory[@"cmd.exe /C C:\odasa\tools\odasa index --auto C:\Project\build.bat"] = @"C:\Project";
|
||||
actions.RunProcess[@"cmd.exe /C C:\Project\build.bat"] = 0;
|
||||
actions.RunProcessWorkingDirectory[@"cmd.exe /C C:\Project\build.bat"] = @"C:\Project";
|
||||
actions.FileExists["csharp.log"] = true;
|
||||
|
||||
var autobuilder = CreateAutoBuilder(true);
|
||||
@@ -686,10 +683,10 @@ namespace Semmle.Autobuild.CSharp.Tests
|
||||
actions.EnumerateDirectories[@"C:\Project"] = "";
|
||||
actions.GetEnvironmentVariable["CODEQL_EXTRACTOR_CSHARP_TRAP_DIR"] = "";
|
||||
actions.GetEnvironmentVariable["CODEQL_EXTRACTOR_CSHARP_SOURCE_ARCHIVE_DIR"] = "";
|
||||
actions.RunProcess[@"cmd.exe /C C:\odasa\tools\odasa index --auto C:\Project\build.bat"] = 1;
|
||||
actions.RunProcessWorkingDirectory[@"cmd.exe /C C:\odasa\tools\odasa index --auto C:\Project\build.bat"] = @"C:\Project";
|
||||
actions.RunProcess[@"cmd.exe /C C:\Project\build.bat"] = 1;
|
||||
actions.RunProcessWorkingDirectory[@"cmd.exe /C C:\Project\build.bat"] = @"C:\Project";
|
||||
actions.RunProcess[@"cmd.exe /C C:\codeql\tools\java\bin\java -jar C:\codeql\csharp\tools\extractor-asp.jar ."] = 0;
|
||||
actions.RunProcess[@"cmd.exe /C C:\odasa\tools\odasa index --xml --extensions config"] = 0;
|
||||
actions.RunProcess[@"cmd.exe /C C:\codeql\tools\codeql index --xml --extensions config"] = 0;
|
||||
actions.FileExists["csharp.log"] = true;
|
||||
|
||||
var autobuilder = CreateAutoBuilder(true, ignoreErrors: "true");
|
||||
@@ -699,9 +696,9 @@ namespace Semmle.Autobuild.CSharp.Tests
|
||||
[Fact]
|
||||
public void TestWindowsCmdIgnoreErrors()
|
||||
{
|
||||
actions.RunProcess["cmd.exe /C C:\\odasa\\tools\\odasa index --auto ^\"build.cmd --skip-tests^\""] = 3;
|
||||
actions.RunProcess["cmd.exe /C ^\"build.cmd --skip-tests^\""] = 3;
|
||||
actions.RunProcess[@"cmd.exe /C C:\codeql\tools\java\bin\java -jar C:\codeql\csharp\tools\extractor-asp.jar ."] = 0;
|
||||
actions.RunProcess[@"cmd.exe /C C:\odasa\tools\odasa index --xml --extensions config"] = 0;
|
||||
actions.RunProcess[@"cmd.exe /C C:\codeql\tools\codeql index --xml --extensions config"] = 0;
|
||||
actions.FileExists["csharp.log"] = true;
|
||||
SkipVsWhere();
|
||||
|
||||
@@ -718,9 +715,9 @@ namespace Semmle.Autobuild.CSharp.Tests
|
||||
public void TestWindowCSharpMsBuild()
|
||||
{
|
||||
actions.RunProcess[@"cmd.exe /C C:\Project\.nuget\nuget.exe restore C:\Project\test1.sln -DisableParallelProcessing"] = 0;
|
||||
actions.RunProcess["cmd.exe /C CALL ^\"C:\\Program Files ^(x86^)\\Microsoft Visual Studio 12.0\\VC\\vcvarsall.bat^\" && set Platform=&& type NUL && C:\\odasa\\tools\\odasa index --auto msbuild C:\\Project\\test1.sln /p:UseSharedCompilation=false /t:Windows /p:Platform=\"x86\" /p:Configuration=\"Debug\" /p:MvcBuildViews=true /P:Fu=Bar"] = 0;
|
||||
actions.RunProcess["cmd.exe /C CALL ^\"C:\\Program Files ^(x86^)\\Microsoft Visual Studio 12.0\\VC\\vcvarsall.bat^\" && set Platform=&& type NUL && msbuild C:\\Project\\test1.sln /p:UseSharedCompilation=false /t:Windows /p:Platform=\"x86\" /p:Configuration=\"Debug\" /p:MvcBuildViews=true /P:Fu=Bar"] = 0;
|
||||
actions.RunProcess[@"cmd.exe /C C:\Project\.nuget\nuget.exe restore C:\Project\test2.sln -DisableParallelProcessing"] = 0;
|
||||
actions.RunProcess["cmd.exe /C CALL ^\"C:\\Program Files ^(x86^)\\Microsoft Visual Studio 12.0\\VC\\vcvarsall.bat^\" && set Platform=&& type NUL && C:\\odasa\\tools\\odasa index --auto msbuild C:\\Project\\test2.sln /p:UseSharedCompilation=false /t:Windows /p:Platform=\"x86\" /p:Configuration=\"Debug\" /p:MvcBuildViews=true /P:Fu=Bar"] = 0;
|
||||
actions.RunProcess["cmd.exe /C CALL ^\"C:\\Program Files ^(x86^)\\Microsoft Visual Studio 12.0\\VC\\vcvarsall.bat^\" && set Platform=&& type NUL && msbuild C:\\Project\\test2.sln /p:UseSharedCompilation=false /t:Windows /p:Platform=\"x86\" /p:Configuration=\"Debug\" /p:MvcBuildViews=true /P:Fu=Bar"] = 0;
|
||||
actions.FileExists["csharp.log"] = true;
|
||||
actions.FileExists[@"C:\Program Files (x86)\Microsoft Visual Studio\Installer\vswhere.exe"] = false;
|
||||
actions.FileExists[@"C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\vcvarsall.bat"] = false;
|
||||
@@ -749,9 +746,9 @@ namespace Semmle.Autobuild.CSharp.Tests
|
||||
public void TestWindowCSharpMsBuildMultipleSolutions()
|
||||
{
|
||||
actions.RunProcess[@"cmd.exe /C nuget restore C:\Project\test1.csproj -DisableParallelProcessing"] = 0;
|
||||
actions.RunProcess["cmd.exe /C CALL ^\"C:\\Program Files ^(x86^)\\Microsoft Visual Studio 12.0\\VC\\vcvarsall.bat^\" && set Platform=&& type NUL && C:\\odasa\\tools\\odasa index --auto msbuild C:\\Project\\test1.csproj /p:UseSharedCompilation=false /t:Windows /p:Platform=\"x86\" /p:Configuration=\"Debug\" /p:MvcBuildViews=true /P:Fu=Bar"] = 0;
|
||||
actions.RunProcess["cmd.exe /C CALL ^\"C:\\Program Files ^(x86^)\\Microsoft Visual Studio 12.0\\VC\\vcvarsall.bat^\" && set Platform=&& type NUL && msbuild C:\\Project\\test1.csproj /p:UseSharedCompilation=false /t:Windows /p:Platform=\"x86\" /p:Configuration=\"Debug\" /p:MvcBuildViews=true /P:Fu=Bar"] = 0;
|
||||
actions.RunProcess[@"cmd.exe /C nuget restore C:\Project\test2.csproj -DisableParallelProcessing"] = 0;
|
||||
actions.RunProcess["cmd.exe /C CALL ^\"C:\\Program Files ^(x86^)\\Microsoft Visual Studio 12.0\\VC\\vcvarsall.bat^\" && set Platform=&& type NUL && C:\\odasa\\tools\\odasa index --auto msbuild C:\\Project\\test2.csproj /p:UseSharedCompilation=false /t:Windows /p:Platform=\"x86\" /p:Configuration=\"Debug\" /p:MvcBuildViews=true /P:Fu=Bar"] = 0;
|
||||
actions.RunProcess["cmd.exe /C CALL ^\"C:\\Program Files ^(x86^)\\Microsoft Visual Studio 12.0\\VC\\vcvarsall.bat^\" && set Platform=&& type NUL && msbuild C:\\Project\\test2.csproj /p:UseSharedCompilation=false /t:Windows /p:Platform=\"x86\" /p:Configuration=\"Debug\" /p:MvcBuildViews=true /P:Fu=Bar"] = 0;
|
||||
actions.FileExists["csharp.log"] = true;
|
||||
actions.FileExists[@"C:\Project\test1.csproj"] = true;
|
||||
actions.FileExists[@"C:\Project\test2.csproj"] = true;
|
||||
@@ -794,7 +791,7 @@ namespace Semmle.Autobuild.CSharp.Tests
|
||||
public void TestWindowCSharpMsBuildFailed()
|
||||
{
|
||||
actions.RunProcess[@"cmd.exe /C nuget restore C:\Project\test1.sln -DisableParallelProcessing"] = 0;
|
||||
actions.RunProcess["cmd.exe /C CALL ^\"C:\\Program Files ^(x86^)\\Microsoft Visual Studio 12.0\\VC\\vcvarsall.bat^\" && set Platform=&& type NUL && C:\\odasa\\tools\\odasa index --auto msbuild C:\\Project\\test1.sln /p:UseSharedCompilation=false /t:Windows /p:Platform=\"x86\" /p:Configuration=\"Debug\" /p:MvcBuildViews=true /P:Fu=Bar"] = 1;
|
||||
actions.RunProcess["cmd.exe /C CALL ^\"C:\\Program Files ^(x86^)\\Microsoft Visual Studio 12.0\\VC\\vcvarsall.bat^\" && set Platform=&& type NUL && msbuild C:\\Project\\test1.sln /p:UseSharedCompilation=false /t:Windows /p:Platform=\"x86\" /p:Configuration=\"Debug\" /p:MvcBuildViews=true /P:Fu=Bar"] = 1;
|
||||
actions.FileExists["csharp.log"] = true;
|
||||
actions.FileExists[@"C:\Program Files (x86)\Microsoft Visual Studio\Installer\vswhere.exe"] = false;
|
||||
actions.FileExists[@"C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\vcvarsall.bat"] = false;
|
||||
@@ -820,8 +817,8 @@ namespace Semmle.Autobuild.CSharp.Tests
|
||||
[Fact]
|
||||
public void TestSkipNugetMsBuild()
|
||||
{
|
||||
actions.RunProcess["cmd.exe /C CALL ^\"C:\\Program Files ^(x86^)\\Microsoft Visual Studio 12.0\\VC\\vcvarsall.bat^\" && set Platform=&& type NUL && C:\\odasa\\tools\\odasa index --auto msbuild C:\\Project\\test1.sln /p:UseSharedCompilation=false /t:Windows /p:Platform=\"x86\" /p:Configuration=\"Debug\" /p:MvcBuildViews=true /P:Fu=Bar"] = 0;
|
||||
actions.RunProcess["cmd.exe /C CALL ^\"C:\\Program Files ^(x86^)\\Microsoft Visual Studio 12.0\\VC\\vcvarsall.bat^\" && set Platform=&& type NUL && C:\\odasa\\tools\\odasa index --auto msbuild C:\\Project\\test2.sln /p:UseSharedCompilation=false /t:Windows /p:Platform=\"x86\" /p:Configuration=\"Debug\" /p:MvcBuildViews=true /P:Fu=Bar"] = 0;
|
||||
actions.RunProcess["cmd.exe /C CALL ^\"C:\\Program Files ^(x86^)\\Microsoft Visual Studio 12.0\\VC\\vcvarsall.bat^\" && set Platform=&& type NUL && msbuild C:\\Project\\test1.sln /p:UseSharedCompilation=false /t:Windows /p:Platform=\"x86\" /p:Configuration=\"Debug\" /p:MvcBuildViews=true /P:Fu=Bar"] = 0;
|
||||
actions.RunProcess["cmd.exe /C CALL ^\"C:\\Program Files ^(x86^)\\Microsoft Visual Studio 12.0\\VC\\vcvarsall.bat^\" && set Platform=&& type NUL && msbuild C:\\Project\\test2.sln /p:UseSharedCompilation=false /t:Windows /p:Platform=\"x86\" /p:Configuration=\"Debug\" /p:MvcBuildViews=true /P:Fu=Bar"] = 0;
|
||||
actions.FileExists["csharp.log"] = true;
|
||||
actions.FileExists[@"C:\Program Files (x86)\Microsoft Visual Studio\Installer\vswhere.exe"] = false;
|
||||
actions.FileExists[@"C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\vcvarsall.bat"] = false;
|
||||
@@ -865,7 +862,7 @@ namespace Semmle.Autobuild.CSharp.Tests
|
||||
actions.RunProcess["dotnet --info"] = 0;
|
||||
actions.RunProcess[@"dotnet clean C:\Project/test.csproj"] = 0;
|
||||
actions.RunProcess[@"dotnet restore C:\Project/test.csproj"] = 0;
|
||||
actions.RunProcess[@"C:\odasa/tools/odasa index --auto dotnet build --no-incremental /p:UseSharedCompilation=false --no-restore C:\Project/test.csproj"] = 0;
|
||||
actions.RunProcess[@"dotnet build --no-incremental /p:UseSharedCompilation=false --no-restore C:\Project/test.csproj"] = 0;
|
||||
actions.FileExists["csharp.log"] = true;
|
||||
actions.FileExists[@"C:\Project/test.csproj"] = true;
|
||||
actions.GetEnvironmentVariable["CODEQL_EXTRACTOR_CSHARP_TRAP_DIR"] = "";
|
||||
@@ -897,7 +894,7 @@ namespace Semmle.Autobuild.CSharp.Tests
|
||||
actions.RunProcess[@"C:\Project/.dotnet/dotnet --info"] = 0;
|
||||
actions.RunProcess[@"C:\Project/.dotnet/dotnet clean C:\Project/test.csproj"] = 0;
|
||||
actions.RunProcess[@"C:\Project/.dotnet/dotnet restore C:\Project/test.csproj"] = 0;
|
||||
actions.RunProcess[@"C:\odasa/tools/odasa index --auto C:\Project/.dotnet/dotnet build --no-incremental /p:UseSharedCompilation=false C:\Project/test.csproj"] = 0;
|
||||
actions.RunProcess[@"C:\Project/.dotnet/dotnet build --no-incremental /p:UseSharedCompilation=false C:\Project/test.csproj"] = 0;
|
||||
actions.FileExists["csharp.log"] = true;
|
||||
actions.FileExists["test.csproj"] = true;
|
||||
actions.GetEnvironmentVariable["CODEQL_EXTRACTOR_CSHARP_TRAP_DIR"] = "";
|
||||
@@ -932,7 +929,7 @@ namespace Semmle.Autobuild.CSharp.Tests
|
||||
actions.RunProcess[@"C:\Project/.dotnet/dotnet --info"] = 0;
|
||||
actions.RunProcess[@"C:\Project/.dotnet/dotnet clean C:\Project/test.csproj"] = 0;
|
||||
actions.RunProcess[@"C:\Project/.dotnet/dotnet restore C:\Project/test.csproj"] = 0;
|
||||
actions.RunProcess[@"C:\odasa/tools/odasa index --auto C:\Project/.dotnet/dotnet build --no-incremental /p:UseSharedCompilation=false C:\Project/test.csproj"] = 0;
|
||||
actions.RunProcess[@"C:\Project/.dotnet/dotnet build --no-incremental /p:UseSharedCompilation=false C:\Project/test.csproj"] = 0;
|
||||
actions.FileExists["csharp.log"] = true;
|
||||
actions.FileExists["test.csproj"] = true;
|
||||
actions.GetEnvironmentVariable["CODEQL_EXTRACTOR_CSHARP_TRAP_DIR"] = "";
|
||||
@@ -963,7 +960,7 @@ namespace Semmle.Autobuild.CSharp.Tests
|
||||
actions.RunProcess[@"cmd.exe /C C:\Project\.dotnet\dotnet --info"] = 0;
|
||||
actions.RunProcess[@"cmd.exe /C C:\Project\.dotnet\dotnet clean C:\Project\test.csproj"] = 0;
|
||||
actions.RunProcess[@"cmd.exe /C C:\Project\.dotnet\dotnet restore C:\Project\test.csproj"] = 0;
|
||||
actions.RunProcess[@"cmd.exe /C C:\odasa\tools\odasa index --auto C:\Project\.dotnet\dotnet build --no-incremental /p:UseSharedCompilation=false C:\Project\test.csproj"] = 0;
|
||||
actions.RunProcess[@"cmd.exe /C C:\Project\.dotnet\dotnet build --no-incremental /p:UseSharedCompilation=false C:\Project\test.csproj"] = 0;
|
||||
actions.FileExists["csharp.log"] = true;
|
||||
actions.FileExists[@"C:\Project\test.csproj"] = true;
|
||||
actions.GetEnvironmentVariable["CODEQL_EXTRACTOR_CSHARP_TRAP_DIR"] = "";
|
||||
@@ -1011,7 +1008,7 @@ namespace Semmle.Autobuild.CSharp.Tests
|
||||
{
|
||||
actions.RunProcess[@"cmd.exe /C nuget restore C:\Project\dirs.proj -DisableParallelProcessing"] = 1;
|
||||
actions.RunProcess[@"cmd.exe /C C:\Project\.nuget\nuget.exe restore C:\Project\dirs.proj -DisableParallelProcessing"] = 0;
|
||||
actions.RunProcess["cmd.exe /C CALL ^\"C:\\Program Files ^(x86^)\\Microsoft Visual Studio 12.0\\VC\\vcvarsall.bat^\" && set Platform=&& type NUL && C:\\odasa\\tools\\odasa index --auto msbuild C:\\Project\\dirs.proj /p:UseSharedCompilation=false /t:Windows /p:Platform=\"x86\" /p:Configuration=\"Debug\" /p:MvcBuildViews=true /P:Fu=Bar"] = 0;
|
||||
actions.RunProcess["cmd.exe /C CALL ^\"C:\\Program Files ^(x86^)\\Microsoft Visual Studio 12.0\\VC\\vcvarsall.bat^\" && set Platform=&& type NUL && msbuild C:\\Project\\dirs.proj /p:UseSharedCompilation=false /t:Windows /p:Platform=\"x86\" /p:Configuration=\"Debug\" /p:MvcBuildViews=true /P:Fu=Bar"] = 0;
|
||||
actions.FileExists["csharp.log"] = true;
|
||||
actions.FileExists[@"C:\Project\a\test.csproj"] = true;
|
||||
actions.FileExists[@"C:\Project\dirs.proj"] = true;
|
||||
@@ -1055,7 +1052,7 @@ namespace Semmle.Autobuild.CSharp.Tests
|
||||
{
|
||||
actions.RunProcess[@"nuget restore C:\Project/dirs.proj -DisableParallelProcessing"] = 1;
|
||||
actions.RunProcess[@"mono C:\Project/.nuget/nuget.exe restore C:\Project/dirs.proj -DisableParallelProcessing"] = 0;
|
||||
actions.RunProcess[@"C:\odasa/tools/odasa index --auto msbuild C:\Project/dirs.proj /p:UseSharedCompilation=false /t:rebuild /p:MvcBuildViews=true"] = 0;
|
||||
actions.RunProcess[@"msbuild C:\Project/dirs.proj /p:UseSharedCompilation=false /t:rebuild /p:MvcBuildViews=true"] = 0;
|
||||
actions.FileExists["csharp.log"] = true;
|
||||
actions.FileExists[@"C:\Project/a/test.csproj"] = true;
|
||||
actions.FileExists[@"C:\Project/dirs.proj"] = true;
|
||||
|
||||
@@ -240,7 +240,7 @@ namespace Semmle.Autobuild.CSharp
|
||||
private static BuildScript GetBuildScript(Autobuilder builder, string? dotNetPath, IDictionary<string, string>? environment, string projOrSln)
|
||||
{
|
||||
var build = new CommandBuilder(builder.Actions, null, environment);
|
||||
var script = builder.MaybeIndex(build, DotNetCommand(builder.Actions, dotNetPath)).
|
||||
var script = build.RunCommand(DotNetCommand(builder.Actions, dotNetPath)).
|
||||
Argument("build").
|
||||
Argument("--no-incremental");
|
||||
|
||||
|
||||
@@ -17,10 +17,6 @@ namespace Semmle.Autobuild.CSharp
|
||||
{
|
||||
standalone = builder.Actions.PathCombine(builder.CodeQLExtractorLangRoot, "tools", builder.CodeQlPlatform, "Semmle.Extraction.CSharp.Standalone");
|
||||
}
|
||||
else if (builder.SemmlePlatformTools is not null)
|
||||
{
|
||||
standalone = builder.Actions.PathCombine(builder.SemmlePlatformTools, "csharp", "Semmle.Extraction.CSharp.Standalone");
|
||||
}
|
||||
else
|
||||
{
|
||||
return BuildScript.Failure;
|
||||
|
||||
@@ -190,19 +190,15 @@ namespace Semmle.Autobuild.Shared
|
||||
});
|
||||
|
||||
CodeQLExtractorLangRoot = Actions.GetEnvironmentVariable($"CODEQL_EXTRACTOR_{this.Options.Language.UpperCaseName}_ROOT");
|
||||
SemmlePlatformTools = Actions.GetEnvironmentVariable("SEMMLE_PLATFORM_TOOLS");
|
||||
|
||||
CodeQlPlatform = Actions.GetEnvironmentVariable("CODEQL_PLATFORM");
|
||||
|
||||
TrapDir =
|
||||
Actions.GetEnvironmentVariable($"CODEQL_EXTRACTOR_{this.Options.Language.UpperCaseName}_TRAP_DIR") ??
|
||||
Actions.GetEnvironmentVariable("TRAP_FOLDER") ??
|
||||
throw new InvalidEnvironmentException($"The environment variable CODEQL_EXTRACTOR_{this.Options.Language.UpperCaseName}_TRAP_DIR or TRAP_FOLDER has not been set.");
|
||||
throw new InvalidEnvironmentException($"The environment variable CODEQL_EXTRACTOR_{this.Options.Language.UpperCaseName}_TRAP_DIR has not been set.");
|
||||
|
||||
SourceArchiveDir =
|
||||
Actions.GetEnvironmentVariable($"CODEQL_EXTRACTOR_{this.Options.Language.UpperCaseName}_SOURCE_ARCHIVE_DIR") ??
|
||||
Actions.GetEnvironmentVariable("SOURCE_ARCHIVE") ??
|
||||
throw new InvalidEnvironmentException($"The environment variable CODEQL_EXTRACTOR_{this.Options.Language.UpperCaseName}_SOURCE_ARCHIVE_DIR or SOURCE_ARCHIVE has not been set.");
|
||||
throw new InvalidEnvironmentException($"The environment variable CODEQL_EXTRACTOR_{this.Options.Language.UpperCaseName}_SOURCE_ARCHIVE_DIR has not been set.");
|
||||
}
|
||||
|
||||
protected string TrapDir { get; }
|
||||
@@ -264,34 +260,9 @@ namespace Semmle.Autobuild.Shared
|
||||
/// </summary>
|
||||
public string? CodeQLExtractorLangRoot { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Value of SEMMLE_PLATFORM_TOOLS environment variable.
|
||||
/// </summary>
|
||||
public string? SemmlePlatformTools { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Value of CODEQL_PLATFORM environment variable.
|
||||
/// </summary>
|
||||
public string? CodeQlPlatform { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The absolute path of the odasa executable.
|
||||
/// null if we are running in CodeQL.
|
||||
/// </summary>
|
||||
public string? Odasa
|
||||
{
|
||||
get
|
||||
{
|
||||
var semmleDist = Actions.GetEnvironmentVariable("SEMMLE_DIST");
|
||||
return semmleDist is null ? null : Actions.PathCombine(semmleDist, "tools", "odasa");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Construct a command that executed the given <paramref name="cmd"/> wrapped in
|
||||
/// an <code>odasa --index</code>, unless indexing has been disabled, in which case
|
||||
/// <paramref name="cmd"/> is run directly.
|
||||
/// </summary>
|
||||
public CommandBuilder MaybeIndex(CommandBuilder builder, string cmd) => Odasa is null ? builder.RunCommand(cmd) : builder.IndexCommand(Odasa, cmd);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -58,7 +58,7 @@ namespace Semmle.Autobuild.Shared
|
||||
if (vsTools is not null)
|
||||
command.CallBatFile(vsTools.Path);
|
||||
|
||||
builder.MaybeIndex(command, scriptPath);
|
||||
command.RunCommand(scriptPath);
|
||||
return command.Script;
|
||||
});
|
||||
}
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
var vsTools = MsBuildRule.GetVcVarsBatFile(builder);
|
||||
if (vsTools is not null)
|
||||
command.CallBatFile(vsTools.Path);
|
||||
builder.MaybeIndex(command, builder.Options.BuildCommand);
|
||||
command.RunCommand(builder.Options.BuildCommand);
|
||||
|
||||
return command.Script;
|
||||
});
|
||||
|
||||
@@ -70,7 +70,7 @@ namespace Semmle.Autobuild.Shared
|
||||
this.environment = environment;
|
||||
}
|
||||
|
||||
public override string ToString() => exe + " " + arguments;
|
||||
public override string ToString() => arguments.Length > 0 ? exe + " " + arguments : exe;
|
||||
|
||||
public override int Run(IBuildActions actions, Action<string, bool> startCallback, Action<int, string, bool> exitCallBack)
|
||||
{
|
||||
|
||||
@@ -45,11 +45,6 @@ namespace Semmle.Autobuild.Shared
|
||||
this.silent = silent;
|
||||
}
|
||||
|
||||
private void OdasaIndex(string odasa)
|
||||
{
|
||||
RunCommand(odasa, "index --auto");
|
||||
}
|
||||
|
||||
public CommandBuilder CallBatFile(string batFile, string? argumentsOpt = null)
|
||||
{
|
||||
NextCommand();
|
||||
@@ -59,21 +54,6 @@ namespace Semmle.Autobuild.Shared
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Perform odasa index on a given command or BAT file.
|
||||
/// </summary>
|
||||
/// <param name="odasa">The odasa executable.</param>
|
||||
/// <param name="command">The command to run.</param>
|
||||
/// <param name="argumentsOpt">Additional arguments.</param>
|
||||
/// <returns>this for chaining calls.</returns>
|
||||
public CommandBuilder IndexCommand(string odasa, string command, string? argumentsOpt = null)
|
||||
{
|
||||
OdasaIndex(odasa);
|
||||
QuoteArgument(command);
|
||||
Argument(argumentsOpt);
|
||||
return this;
|
||||
}
|
||||
|
||||
private static readonly char[] specialChars = { ' ', '\t', '\n', '\v', '\"' };
|
||||
private static readonly char[] cmdMetacharacter = { '(', ')', '%', '!', '^', '\"', '<', '>', '&', '|' };
|
||||
|
||||
|
||||
@@ -95,7 +95,7 @@ namespace Semmle.Autobuild.Shared
|
||||
command.RunCommand("set Platform=&& type NUL", quoteExe: false);
|
||||
}
|
||||
|
||||
builder.MaybeIndex(command, msBuild);
|
||||
command.RunCommand(msBuild);
|
||||
command.QuoteArgument(projectOrSolution.FullPath);
|
||||
|
||||
command.Argument("/p:UseSharedCompilation=false");
|
||||
|
||||
@@ -1,14 +0,0 @@
|
||||
**/mcs.exe:
|
||||
**/csc.exe:
|
||||
invoke ${env.SEMMLE_PLATFORM_TOOLS}/csharp/Semmle.Extraction.CSharp.Driver
|
||||
prepend --compiler
|
||||
prepend "${compiler}"
|
||||
prepend --cil
|
||||
**/mono*:
|
||||
**/dotnet:
|
||||
invoke ${odasa_tools}/extract-csharp.sh
|
||||
**/msbuild:
|
||||
**/xbuild:
|
||||
replace yes
|
||||
invoke ${compiler}
|
||||
append /p:UseSharedCompilation=false
|
||||
@@ -1,16 +0,0 @@
|
||||
#!/bin/bash
|
||||
echo extract-csharp.sh: Called with arguments: "$@"
|
||||
|
||||
extractor=$SEMMLE_PLATFORM_TOOLS/csharp/Semmle.Extraction.CSharp.Driver
|
||||
|
||||
for i in "$@"
|
||||
do
|
||||
shift
|
||||
if [[ `basename -- "$i"` =~ csc.exe|mcs.exe|csc.dll ]]
|
||||
then
|
||||
echo extract-csharp.sh: exec $extractor --cil $@
|
||||
exec "$extractor" --compiler $i --cil $@
|
||||
fi
|
||||
done
|
||||
|
||||
echo extract-csharp.sh: Not a compiler invocation
|
||||
@@ -1,9 +0,0 @@
|
||||
**\fakes*.exe:
|
||||
**\moles*.exe:
|
||||
order compiler
|
||||
trace no
|
||||
**\csc*.exe:
|
||||
invoke ${env.SEMMLE_PLATFORM_TOOLS}\csharp\Semmle.Extraction.CSharp.Driver.exe
|
||||
prepend --compiler
|
||||
prepend "${compiler}"
|
||||
prepend --cil
|
||||
@@ -20,11 +20,11 @@ namespace Semmle.Extraction.CIL.Driver
|
||||
Console.WriteLine(" path A directory/dll/exe to analyze");
|
||||
}
|
||||
|
||||
private static void ExtractAssembly(Layout layout, string assemblyPath, ILogger logger, CommonOptions options)
|
||||
private static void ExtractAssembly(string assemblyPath, ILogger logger, CommonOptions options)
|
||||
{
|
||||
var sw = new Stopwatch();
|
||||
sw.Start();
|
||||
Analyser.ExtractCIL(layout, assemblyPath, logger, options, out _, out _);
|
||||
Analyser.ExtractCIL(assemblyPath, logger, options, out _, out _);
|
||||
sw.Stop();
|
||||
logger.Log(Severity.Info, " {0} ({1})", assemblyPath, sw.Elapsed);
|
||||
}
|
||||
@@ -38,12 +38,11 @@ namespace Semmle.Extraction.CIL.Driver
|
||||
}
|
||||
|
||||
var options = new ExtractorOptions(args);
|
||||
var layout = new Layout();
|
||||
using var logger = new ConsoleLogger(options.Verbosity);
|
||||
|
||||
var actions = options.AssembliesToExtract
|
||||
.Select(asm => asm.Filename)
|
||||
.Select<string, Action>(filename => () => ExtractAssembly(layout, filename, logger, options))
|
||||
.Select<string, Action>(filename => () => ExtractAssembly(filename, logger, options))
|
||||
.ToArray();
|
||||
|
||||
foreach (var missingRef in options.MissingReferences)
|
||||
|
||||
@@ -25,7 +25,7 @@ namespace Semmle.Extraction.CIL
|
||||
/// <param name="extractPdbs">Whether to extract PDBs.</param>
|
||||
/// <param name="trapFile">The path of the trap file.</param>
|
||||
/// <param name="extracted">Whether the file was extracted (false=cached).</param>
|
||||
public static void ExtractCIL(Layout layout, string assemblyPath, ILogger logger, CommonOptions options, out string trapFile, out bool extracted)
|
||||
public static void ExtractCIL(string assemblyPath, ILogger logger, CommonOptions options, out string trapFile, out bool extracted)
|
||||
{
|
||||
trapFile = "";
|
||||
extracted = false;
|
||||
@@ -35,8 +35,7 @@ namespace Semmle.Extraction.CIL
|
||||
var pathTransformer = new PathTransformer(canonicalPathCache);
|
||||
var extractor = new TracingExtractor(assemblyPath, logger, pathTransformer, options);
|
||||
var transformedAssemblyPath = pathTransformer.Transform(assemblyPath);
|
||||
var project = layout.LookupProjectOrDefault(transformedAssemblyPath);
|
||||
using var trapWriter = project.CreateTrapWriter(logger, transformedAssemblyPath.WithSuffix(".cil"), options.TrapCompression, discardDuplicates: true);
|
||||
using var trapWriter = transformedAssemblyPath.WithSuffix(".cil").CreateTrapWriter(logger, options.TrapCompression, discardDuplicates: true);
|
||||
trapFile = trapWriter.TrapFile;
|
||||
if (!options.Cache || !System.IO.File.Exists(trapFile))
|
||||
{
|
||||
|
||||
@@ -84,7 +84,7 @@ namespace Semmle.Extraction.CSharp.Standalone
|
||||
foreach (var r in DesktopRuntimes)
|
||||
yield return r;
|
||||
|
||||
// A bad choice if it's the self-contained runtime distributed in odasa dist.
|
||||
// A bad choice if it's the self-contained runtime distributed in codeql dist.
|
||||
yield return ExecutingRuntime;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,7 +14,6 @@ namespace Semmle.Extraction.CSharp
|
||||
public void Initialize(CSharpCompilation compilationIn, CommonOptions options)
|
||||
{
|
||||
compilation = compilationIn;
|
||||
layout = new Layout();
|
||||
extractor = new StandaloneExtractor(Logger, PathTransformer, options);
|
||||
this.options = options;
|
||||
LogExtractorInfo(Extraction.Extractor.Version);
|
||||
|
||||
@@ -18,7 +18,6 @@ namespace Semmle.Extraction.CSharp
|
||||
{
|
||||
protected Extraction.Extractor? extractor;
|
||||
protected CSharpCompilation? compilation;
|
||||
protected Layout? layout;
|
||||
protected CommonOptions? options;
|
||||
|
||||
private readonly object progressMutex = new object();
|
||||
@@ -125,8 +124,7 @@ namespace Semmle.Extraction.CSharp
|
||||
|
||||
var assemblyPath = r.FilePath!;
|
||||
var transformedAssemblyPath = PathTransformer.Transform(assemblyPath);
|
||||
var projectLayout = layout.LookupProjectOrDefault(transformedAssemblyPath);
|
||||
using var trapWriter = projectLayout.CreateTrapWriter(Logger, transformedAssemblyPath, options.TrapCompression, discardDuplicates: true);
|
||||
using var trapWriter = transformedAssemblyPath.CreateTrapWriter(Logger, options.TrapCompression, discardDuplicates: true);
|
||||
|
||||
var skipExtraction = options.Cache && File.Exists(trapWriter.TrapFile);
|
||||
|
||||
@@ -178,7 +176,7 @@ namespace Semmle.Extraction.CSharp
|
||||
{
|
||||
var stopwatch = new Stopwatch();
|
||||
stopwatch.Start();
|
||||
CIL.Analyser.ExtractCIL(layout, r.FilePath!, Logger, options, out var trapFile, out var extracted);
|
||||
CIL.Analyser.ExtractCIL(r.FilePath!, Logger, options, out var trapFile, out var extracted);
|
||||
stopwatch.Stop();
|
||||
ReportProgress(r.FilePath, trapFile, stopwatch.Elapsed, extracted ? AnalysisAction.Extracted : AnalysisAction.UpToDate);
|
||||
}
|
||||
@@ -192,44 +190,35 @@ namespace Semmle.Extraction.CSharp
|
||||
var sourcePath = tree.FilePath;
|
||||
var transformedSourcePath = PathTransformer.Transform(sourcePath);
|
||||
|
||||
var projectLayout = layout.LookupProjectOrNull(transformedSourcePath);
|
||||
var excluded = projectLayout is null;
|
||||
var trapPath = excluded ? "" : projectLayout!.GetTrapPath(Logger, transformedSourcePath, options.TrapCompression);
|
||||
var trapPath = transformedSourcePath.GetTrapPath(Logger, options.TrapCompression);
|
||||
var upToDate = false;
|
||||
|
||||
if (!excluded)
|
||||
// compilation.Clone() is used to allow symbols to be garbage collected.
|
||||
using var trapWriter = transformedSourcePath.CreateTrapWriter(Logger, options.TrapCompression, discardDuplicates: false);
|
||||
|
||||
upToDate = options.Fast && FileIsUpToDate(sourcePath, trapWriter.TrapFile);
|
||||
|
||||
if (!upToDate)
|
||||
{
|
||||
// compilation.Clone() is used to allow symbols to be garbage collected.
|
||||
using var trapWriter = projectLayout!.CreateTrapWriter(Logger, transformedSourcePath, options.TrapCompression, discardDuplicates: false);
|
||||
var cx = new Context(extractor, compilation.Clone(), trapWriter, new SourceScope(tree), addAssemblyTrapPrefix);
|
||||
// Ensure that the file itself is populated in case the source file is totally empty
|
||||
var root = tree.GetRoot();
|
||||
Entities.File.Create(cx, root.SyntaxTree.FilePath);
|
||||
|
||||
upToDate = options.Fast && FileIsUpToDate(sourcePath, trapWriter.TrapFile);
|
||||
|
||||
if (!upToDate)
|
||||
var csNode = (CSharpSyntaxNode)root;
|
||||
var directiveVisitor = new DirectiveVisitor(cx);
|
||||
csNode.Accept(directiveVisitor);
|
||||
foreach (var branch in directiveVisitor.BranchesTaken)
|
||||
{
|
||||
var cx = new Context(extractor, compilation.Clone(), trapWriter, new SourceScope(tree), addAssemblyTrapPrefix);
|
||||
// Ensure that the file itself is populated in case the source file is totally empty
|
||||
var root = tree.GetRoot();
|
||||
Entities.File.Create(cx, root.SyntaxTree.FilePath);
|
||||
|
||||
var csNode = (CSharpSyntaxNode)root;
|
||||
var directiveVisitor = new DirectiveVisitor(cx);
|
||||
csNode.Accept(directiveVisitor);
|
||||
foreach (var branch in directiveVisitor.BranchesTaken)
|
||||
{
|
||||
cx.TrapStackSuffix.Add(branch);
|
||||
}
|
||||
csNode.Accept(new CompilationUnitVisitor(cx));
|
||||
cx.PopulateAll();
|
||||
CommentPopulator.ExtractCommentBlocks(cx, cx.CommentGenerator);
|
||||
cx.PopulateAll();
|
||||
cx.TrapStackSuffix.Add(branch);
|
||||
}
|
||||
csNode.Accept(new CompilationUnitVisitor(cx));
|
||||
cx.PopulateAll();
|
||||
CommentPopulator.ExtractCommentBlocks(cx, cx.CommentGenerator);
|
||||
cx.PopulateAll();
|
||||
}
|
||||
|
||||
ReportProgress(sourcePath, trapPath, stopwatch.Elapsed, excluded
|
||||
? AnalysisAction.Excluded
|
||||
: upToDate
|
||||
? AnalysisAction.UpToDate
|
||||
: AnalysisAction.Extracted);
|
||||
ReportProgress(sourcePath, trapPath, stopwatch.Elapsed, upToDate ? AnalysisAction.UpToDate : AnalysisAction.Extracted);
|
||||
}
|
||||
catch (Exception ex) // lgtm[cs/catch-of-all-exceptions]
|
||||
{
|
||||
|
||||
@@ -452,19 +452,6 @@ namespace Semmle.Extraction.CSharp
|
||||
if (!string.IsNullOrEmpty(codeQlLogDir))
|
||||
return codeQlLogDir;
|
||||
|
||||
var snapshot = Environment.GetEnvironmentVariable("ODASA_SNAPSHOT");
|
||||
if (!string.IsNullOrEmpty(snapshot))
|
||||
return Path.Combine(snapshot, "log");
|
||||
|
||||
var buildErrorDir = Environment.GetEnvironmentVariable("ODASA_BUILD_ERROR_DIR");
|
||||
if (!string.IsNullOrEmpty(buildErrorDir))
|
||||
// Used by `qltest`
|
||||
return buildErrorDir;
|
||||
|
||||
var traps = Environment.GetEnvironmentVariable("TRAP_FOLDER");
|
||||
if (!string.IsNullOrEmpty(traps))
|
||||
return traps;
|
||||
|
||||
return Directory.GetCurrentDirectory();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -40,8 +40,7 @@ namespace Semmle.Extraction.CSharp
|
||||
public static Options CreateWithEnvironment(string[] arguments)
|
||||
{
|
||||
var options = new Options();
|
||||
var extractionOptions = Environment.GetEnvironmentVariable("SEMMLE_EXTRACTOR_OPTIONS") ??
|
||||
Environment.GetEnvironmentVariable("LGTM_INDEX_EXTRACTOR");
|
||||
var extractionOptions = Environment.GetEnvironmentVariable("LGTM_INDEX_EXTRACTOR");
|
||||
|
||||
var argsList = new List<string>(arguments);
|
||||
|
||||
|
||||
@@ -46,7 +46,6 @@ namespace Semmle.Extraction.CSharp
|
||||
{
|
||||
if (!init)
|
||||
throw new InternalError("EndInitialize called without BeginInitialize returning true");
|
||||
this.layout = new Layout();
|
||||
this.options = options;
|
||||
this.compilation = compilation;
|
||||
this.extractor = new TracingExtractor(GetOutputName(compilation, commandLineArguments), Logger, PathTransformer, options);
|
||||
@@ -202,8 +201,7 @@ namespace Semmle.Extraction.CSharp
|
||||
var assemblyPath = ((TracingExtractor?)extractor).OutputPath;
|
||||
var transformedAssemblyPath = PathTransformer.Transform(assemblyPath);
|
||||
var assembly = compilation.Assembly;
|
||||
var projectLayout = layout.LookupProjectOrDefault(transformedAssemblyPath);
|
||||
var trapWriter = projectLayout.CreateTrapWriter(Logger, transformedAssemblyPath, options.TrapCompression, discardDuplicates: false);
|
||||
var trapWriter = transformedAssemblyPath.CreateTrapWriter(Logger, options.TrapCompression, discardDuplicates: false);
|
||||
compilationTrapFile = trapWriter; // Dispose later
|
||||
var cx = new Context(extractor, compilation.Clone(), trapWriter, new AssemblyScope(assembly, assemblyPath), addAssemblyTrapPrefix);
|
||||
|
||||
|
||||
@@ -1,231 +0,0 @@
|
||||
using System.IO;
|
||||
using Xunit;
|
||||
using Semmle.Util.Logging;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace Semmle.Extraction.Tests
|
||||
{
|
||||
internal struct TransformedPathStub : PathTransformer.ITransformedPath
|
||||
{
|
||||
private readonly string value;
|
||||
public TransformedPathStub(string value) => this.value = value;
|
||||
public string Value => value;
|
||||
|
||||
public string Extension => throw new System.NotImplementedException();
|
||||
|
||||
public string NameWithoutExtension => throw new System.NotImplementedException();
|
||||
|
||||
public PathTransformer.ITransformedPath ParentDirectory => throw new System.NotImplementedException();
|
||||
|
||||
public string DatabaseId => throw new System.NotImplementedException();
|
||||
|
||||
public PathTransformer.ITransformedPath WithSuffix(string suffix)
|
||||
{
|
||||
throw new System.NotImplementedException();
|
||||
}
|
||||
}
|
||||
|
||||
public class Layout
|
||||
{
|
||||
private readonly ILogger logger = new LoggerMock();
|
||||
|
||||
[Fact]
|
||||
public void TestDefaultLayout()
|
||||
{
|
||||
var layout = new Semmle.Extraction.Layout(null, null, null);
|
||||
var project = layout.LookupProjectOrNull(new TransformedPathStub("foo.cs"));
|
||||
|
||||
Assert.NotNull(project);
|
||||
|
||||
// All files are mapped when there's no layout file.
|
||||
Assert.True(layout.FileInLayout(new TransformedPathStub("foo.cs")));
|
||||
|
||||
// Test trap filename
|
||||
var tmpDir = Path.GetTempPath();
|
||||
Directory.SetCurrentDirectory(tmpDir);
|
||||
if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX))
|
||||
{
|
||||
// `Directory.SetCurrentDirectory()` seems to slightly change the path on macOS,
|
||||
// so adjusting it:
|
||||
Assert.NotEqual(Directory.GetCurrentDirectory(), tmpDir);
|
||||
tmpDir = "/private" + tmpDir;
|
||||
// Remove trailing slash:
|
||||
Assert.Equal('/', tmpDir[tmpDir.Length - 1]);
|
||||
tmpDir = tmpDir.Substring(0, tmpDir.Length - 1);
|
||||
Assert.Equal(Directory.GetCurrentDirectory(), tmpDir);
|
||||
}
|
||||
var f1 = project!.GetTrapPath(logger, new TransformedPathStub("foo.cs"), TrapWriter.CompressionMode.Gzip);
|
||||
var g1 = TrapWriter.NestPaths(logger, tmpDir, "foo.cs.trap.gz");
|
||||
Assert.Equal(f1, g1);
|
||||
|
||||
// Test trap file generation
|
||||
var trapwriterFilename = project.GetTrapPath(logger, new TransformedPathStub("foo.cs"), TrapWriter.CompressionMode.Gzip);
|
||||
using (var trapwriter = project.CreateTrapWriter(logger, new TransformedPathStub("foo.cs"), TrapWriter.CompressionMode.Gzip, discardDuplicates: false))
|
||||
{
|
||||
trapwriter.Emit("1=*");
|
||||
Assert.False(File.Exists(trapwriterFilename));
|
||||
}
|
||||
Assert.True(File.Exists(trapwriterFilename));
|
||||
File.Delete(trapwriterFilename);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void TestLayoutFile()
|
||||
{
|
||||
File.WriteAllLines("layout.txt", new string[]
|
||||
{
|
||||
"# Section",
|
||||
"TRAP_FOLDER=" + Path.GetFullPath("snapshot\\trap"),
|
||||
"ODASA_DB=snapshot\\db-csharp",
|
||||
"SOURCE_ARCHIVE=" + Path.GetFullPath("snapshot\\archive"),
|
||||
"ODASA_BUILD_ERROR_DIR=snapshot\build-errors",
|
||||
"-foo.cs",
|
||||
"bar.cs",
|
||||
"-excluded",
|
||||
"excluded/foo.cs",
|
||||
"included"
|
||||
});
|
||||
|
||||
var layout = new Semmle.Extraction.Layout(null, null, "layout.txt");
|
||||
|
||||
// Test general pattern matching
|
||||
Assert.True(layout.FileInLayout(new TransformedPathStub("bar.cs")));
|
||||
Assert.False(layout.FileInLayout(new TransformedPathStub("foo.cs")));
|
||||
Assert.False(layout.FileInLayout(new TransformedPathStub("goo.cs")));
|
||||
Assert.False(layout.FileInLayout(new TransformedPathStub("excluded/bar.cs")));
|
||||
Assert.True(layout.FileInLayout(new TransformedPathStub("excluded/foo.cs")));
|
||||
Assert.True(layout.FileInLayout(new TransformedPathStub("included/foo.cs")));
|
||||
|
||||
// Test the trap file
|
||||
var project = layout.LookupProjectOrNull(new TransformedPathStub("bar.cs"));
|
||||
Assert.NotNull(project);
|
||||
var trapwriterFilename = project!.GetTrapPath(logger, new TransformedPathStub("bar.cs"), TrapWriter.CompressionMode.Gzip);
|
||||
Assert.Equal(TrapWriter.NestPaths(logger, Path.GetFullPath("snapshot\\trap"), "bar.cs.trap.gz"),
|
||||
trapwriterFilename);
|
||||
|
||||
// Test the source archive
|
||||
var trapWriter = project.CreateTrapWriter(logger, new TransformedPathStub("bar.cs"), TrapWriter.CompressionMode.Gzip, discardDuplicates: false);
|
||||
trapWriter.Archive("layout.txt", new TransformedPathStub("layout.txt"), System.Text.Encoding.ASCII);
|
||||
var writtenFile = TrapWriter.NestPaths(logger, Path.GetFullPath("snapshot\\archive"), "layout.txt");
|
||||
Assert.True(File.Exists(writtenFile));
|
||||
File.Delete("layout.txt");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void TestTrapOverridesLayout()
|
||||
{
|
||||
// When you specify both a trap file and a layout, use the trap file.
|
||||
var layout = new Semmle.Extraction.Layout(Path.GetFullPath("snapshot\\trap"), null, "something.txt");
|
||||
Assert.True(layout.FileInLayout(new TransformedPathStub("bar.cs")));
|
||||
var subProject = layout.LookupProjectOrNull(new TransformedPathStub("foo.cs"));
|
||||
Assert.NotNull(subProject);
|
||||
var f1 = subProject!.GetTrapPath(logger, new TransformedPathStub("foo.cs"), TrapWriter.CompressionMode.Gzip);
|
||||
var g1 = TrapWriter.NestPaths(logger, Path.GetFullPath("snapshot\\trap"), "foo.cs.trap.gz");
|
||||
Assert.Equal(f1, g1);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void TestMultipleSections()
|
||||
{
|
||||
File.WriteAllLines("layout.txt", new string[]
|
||||
{
|
||||
"# Section 1",
|
||||
"TRAP_FOLDER=" + Path.GetFullPath("snapshot\\trap1"),
|
||||
"ODASA_DB=snapshot\\db-csharp",
|
||||
"SOURCE_ARCHIVE=" + Path.GetFullPath("snapshot\\archive1"),
|
||||
"ODASA_BUILD_ERROR_DIR=snapshot\build-errors",
|
||||
"foo.cs",
|
||||
"# Section 2",
|
||||
"TRAP_FOLDER=" + Path.GetFullPath("snapshot\\trap2"),
|
||||
"ODASA_DB=snapshot\\db-csharp",
|
||||
"SOURCE_ARCHIVE=" + Path.GetFullPath("snapshot\\archive2"),
|
||||
"ODASA_BUILD_ERROR_DIR=snapshot\build-errors",
|
||||
"bar.cs",
|
||||
});
|
||||
|
||||
var layout = new Semmle.Extraction.Layout(null, null, "layout.txt");
|
||||
|
||||
// Use Section 2
|
||||
Assert.True(layout.FileInLayout(new TransformedPathStub("bar.cs")));
|
||||
var subProject = layout.LookupProjectOrNull(new TransformedPathStub("bar.cs"));
|
||||
Assert.NotNull(subProject);
|
||||
var f1 = subProject!.GetTrapPath(logger, new TransformedPathStub("bar.cs"), TrapWriter.CompressionMode.Gzip);
|
||||
var g1 = TrapWriter.NestPaths(logger, Path.GetFullPath("snapshot\\trap2"), "bar.cs.trap.gz");
|
||||
Assert.Equal(f1, g1);
|
||||
|
||||
// Use Section 1
|
||||
Assert.True(layout.FileInLayout(new TransformedPathStub("foo.cs")));
|
||||
subProject = layout.LookupProjectOrNull(new TransformedPathStub("foo.cs"));
|
||||
Assert.NotNull(subProject);
|
||||
var f2 = subProject!.GetTrapPath(logger, new TransformedPathStub("foo.cs"), TrapWriter.CompressionMode.Gzip);
|
||||
var g2 = TrapWriter.NestPaths(logger, Path.GetFullPath("snapshot\\trap1"), "foo.cs.trap.gz");
|
||||
Assert.Equal(f2, g2);
|
||||
|
||||
// boo.dll is not in the layout, so use layout from first section.
|
||||
Assert.False(layout.FileInLayout(new TransformedPathStub("boo.dll")));
|
||||
var f3 = layout.LookupProjectOrDefault(new TransformedPathStub("boo.dll")).GetTrapPath(logger, new TransformedPathStub("boo.dll"), TrapWriter.CompressionMode.Gzip);
|
||||
var g3 = TrapWriter.NestPaths(logger, Path.GetFullPath("snapshot\\trap1"), "boo.dll.trap.gz");
|
||||
Assert.Equal(f3, g3);
|
||||
|
||||
// boo.cs is not in the layout, so return null
|
||||
Assert.False(layout.FileInLayout(new TransformedPathStub("boo.cs")));
|
||||
Assert.Null(layout.LookupProjectOrNull(new TransformedPathStub("boo.cs")));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void MissingLayout()
|
||||
{
|
||||
Assert.Throws<Extraction.Layout.InvalidLayoutException>(() =>
|
||||
new Semmle.Extraction.Layout(null, null, "nosuchfile.txt"));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void EmptyLayout()
|
||||
{
|
||||
File.Create("layout.txt").Close();
|
||||
Assert.Throws<Extraction.Layout.InvalidLayoutException>(() =>
|
||||
new Semmle.Extraction.Layout(null, null, "layout.txt"));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void InvalidLayout()
|
||||
{
|
||||
File.WriteAllLines("layout.txt", new string[]
|
||||
{
|
||||
"# Section 1"
|
||||
});
|
||||
|
||||
Assert.Throws<Extraction.Layout.InvalidLayoutException>(() =>
|
||||
new Semmle.Extraction.Layout(null, null, "layout.txt"));
|
||||
}
|
||||
|
||||
private sealed class LoggerMock : ILogger
|
||||
{
|
||||
public void Dispose() { }
|
||||
|
||||
public void Log(Severity s, string text) { }
|
||||
}
|
||||
}
|
||||
|
||||
internal static class TrapWriterTestExtensions
|
||||
{
|
||||
public static void Emit(this TrapWriter trapFile, string s)
|
||||
{
|
||||
trapFile.Emit(new StringTrapEmitter(s));
|
||||
}
|
||||
|
||||
private class StringTrapEmitter : ITrapEmitter
|
||||
{
|
||||
private readonly string content;
|
||||
public StringTrapEmitter(string content)
|
||||
{
|
||||
this.content = content;
|
||||
}
|
||||
|
||||
public void EmitTrap(TextWriter trapFile)
|
||||
{
|
||||
trapFile.Write(content);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -14,7 +14,6 @@ namespace Semmle.Extraction.Tests
|
||||
|
||||
public OptionsTests()
|
||||
{
|
||||
Environment.SetEnvironmentVariable("SEMMLE_EXTRACTOR_OPTIONS", "");
|
||||
Environment.SetEnvironmentVariable("LGTM_INDEX_EXTRACTOR", "");
|
||||
}
|
||||
|
||||
@@ -126,14 +125,14 @@ namespace Semmle.Extraction.Tests
|
||||
[Fact]
|
||||
public void EnvironmentVariables()
|
||||
{
|
||||
Environment.SetEnvironmentVariable("SEMMLE_EXTRACTOR_OPTIONS", "--cil c");
|
||||
Environment.SetEnvironmentVariable("LGTM_INDEX_EXTRACTOR", "--cil c");
|
||||
options = CSharp.Options.CreateWithEnvironment(new string[] { "a", "b" });
|
||||
Assert.True(options.CIL);
|
||||
Assert.Equal("a", options.CompilerArguments[0]);
|
||||
Assert.Equal("b", options.CompilerArguments[1]);
|
||||
Assert.Equal("c", options.CompilerArguments[2]);
|
||||
|
||||
Environment.SetEnvironmentVariable("SEMMLE_EXTRACTOR_OPTIONS", "");
|
||||
Environment.SetEnvironmentVariable("LGTM_INDEX_EXTRACTOR", "");
|
||||
Environment.SetEnvironmentVariable("LGTM_INDEX_EXTRACTOR", "--nocil");
|
||||
options = CSharp.Options.CreateWithEnvironment(new string[] { "--cil" });
|
||||
Assert.False(options.CIL);
|
||||
|
||||
@@ -1,204 +0,0 @@
|
||||
using Semmle.Util.Logging;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
|
||||
namespace Semmle.Extraction
|
||||
{
|
||||
/// <summary>
|
||||
/// An extractor layout file.
|
||||
/// Represents the layout of projects into trap folders and source archives.
|
||||
/// </summary>
|
||||
public sealed class Layout
|
||||
{
|
||||
/// <summary>
|
||||
/// Exception thrown when the layout file is invalid.
|
||||
/// </summary>
|
||||
public class InvalidLayoutException : Exception
|
||||
{
|
||||
public InvalidLayoutException(string file, string message) :
|
||||
base("ODASA_CSHARP_LAYOUT " + file + " " + message)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// List of blocks in the layout file.
|
||||
/// </summary>
|
||||
private readonly List<LayoutBlock> blocks;
|
||||
|
||||
/// <summary>
|
||||
/// A subproject in the layout file.
|
||||
/// </summary>
|
||||
public class SubProject
|
||||
{
|
||||
/// <summary>
|
||||
/// The trap folder, or null for current directory.
|
||||
/// </summary>
|
||||
public string? TRAP_FOLDER { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The source archive, or null to skip.
|
||||
/// </summary>
|
||||
public string? SOURCE_ARCHIVE { get; }
|
||||
|
||||
public SubProject(string? traps, string? archive)
|
||||
{
|
||||
TRAP_FOLDER = traps;
|
||||
SOURCE_ARCHIVE = archive;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the name of the trap file for a given source/assembly file.
|
||||
/// </summary>
|
||||
/// <param name="srcFile">The source file.</param>
|
||||
/// <returns>The full filepath of the trap file.</returns>
|
||||
public string GetTrapPath(ILogger logger, PathTransformer.ITransformedPath srcFile, TrapWriter.CompressionMode trapCompression) =>
|
||||
TrapWriter.TrapPath(logger, TRAP_FOLDER, srcFile, trapCompression);
|
||||
|
||||
/// <summary>
|
||||
/// Creates a trap writer for a given source/assembly file.
|
||||
/// </summary>
|
||||
/// <param name="srcFile">The source file.</param>
|
||||
/// <returns>A newly created TrapWriter.</returns>
|
||||
public TrapWriter CreateTrapWriter(ILogger logger, PathTransformer.ITransformedPath srcFile, TrapWriter.CompressionMode trapCompression, bool discardDuplicates) =>
|
||||
new TrapWriter(logger, srcFile, TRAP_FOLDER, SOURCE_ARCHIVE, trapCompression, discardDuplicates);
|
||||
}
|
||||
|
||||
private readonly SubProject defaultProject;
|
||||
|
||||
/// <summary>
|
||||
/// Finds the suitable directories for a given source file.
|
||||
/// Returns null if not included in the layout.
|
||||
/// </summary>
|
||||
/// <param name="sourceFile">The file to look up.</param>
|
||||
/// <returns>The relevant subproject, or null if not found.</returns>
|
||||
public SubProject? LookupProjectOrNull(PathTransformer.ITransformedPath sourceFile)
|
||||
{
|
||||
if (!useLayoutFile)
|
||||
return defaultProject;
|
||||
|
||||
return blocks
|
||||
.Where(block => block.Matches(sourceFile))
|
||||
.Select(block => block.Directories)
|
||||
.FirstOrDefault();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Finds the suitable directories for a given source file.
|
||||
/// Returns the default project if not included in the layout.
|
||||
/// </summary>
|
||||
/// <param name="sourceFile">The file to look up.</param>
|
||||
/// <returns>The relevant subproject, or DefaultProject if not found.</returns>
|
||||
public SubProject LookupProjectOrDefault(PathTransformer.ITransformedPath sourceFile)
|
||||
{
|
||||
return LookupProjectOrNull(sourceFile) ?? defaultProject;
|
||||
}
|
||||
|
||||
private readonly bool useLayoutFile;
|
||||
|
||||
/// <summary>
|
||||
/// Default constructor reads parameters from the environment.
|
||||
/// </summary>
|
||||
public Layout() : this(
|
||||
Environment.GetEnvironmentVariable("CODEQL_EXTRACTOR_CSHARP_TRAP_DIR") ?? Environment.GetEnvironmentVariable("TRAP_FOLDER"),
|
||||
Environment.GetEnvironmentVariable("CODEQL_EXTRACTOR_CSHARP_SOURCE_ARCHIVE_DIR") ?? Environment.GetEnvironmentVariable("SOURCE_ARCHIVE"),
|
||||
Environment.GetEnvironmentVariable("ODASA_CSHARP_LAYOUT"))
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates the project layout. Reads the layout file if specified.
|
||||
/// </summary>
|
||||
/// <param name="traps">Directory for trap files, or null to use layout/current directory.</param>
|
||||
/// <param name="archive">Directory for source archive, or null for layout/no archive.</param>
|
||||
/// <param name="layout">Path of layout file, or null for no layout.</param>
|
||||
/// <exception cref="InvalidLayoutException">Failed to read layout file.</exception>
|
||||
public Layout(string? traps, string? archive, string? layout)
|
||||
{
|
||||
useLayoutFile = string.IsNullOrEmpty(traps) && !string.IsNullOrEmpty(layout);
|
||||
blocks = new List<LayoutBlock>();
|
||||
|
||||
if (useLayoutFile)
|
||||
{
|
||||
ReadLayoutFile(layout!);
|
||||
defaultProject = blocks[0].Directories;
|
||||
}
|
||||
else
|
||||
{
|
||||
defaultProject = new SubProject(traps, archive);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Is the source file included in the layout?
|
||||
/// </summary>
|
||||
/// <param name="path">The absolute path of the file to query.</param>
|
||||
/// <returns>True iff there is no layout file or the layout file specifies the file.</returns>
|
||||
public bool FileInLayout(PathTransformer.ITransformedPath path) => LookupProjectOrNull(path) is not null;
|
||||
|
||||
private void ReadLayoutFile(string layout)
|
||||
{
|
||||
try
|
||||
{
|
||||
var lines = File.ReadAllLines(layout);
|
||||
|
||||
var i = 0;
|
||||
while (!lines[i].StartsWith("#"))
|
||||
i++;
|
||||
while (i < lines.Length)
|
||||
{
|
||||
var block = new LayoutBlock(lines, ref i);
|
||||
blocks.Add(block);
|
||||
}
|
||||
|
||||
if (blocks.Count == 0)
|
||||
throw new InvalidLayoutException(layout, "contains no blocks");
|
||||
}
|
||||
catch (IOException ex)
|
||||
{
|
||||
throw new InvalidLayoutException(layout, ex.Message);
|
||||
}
|
||||
catch (IndexOutOfRangeException)
|
||||
{
|
||||
throw new InvalidLayoutException(layout, "is invalid");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal sealed class LayoutBlock
|
||||
{
|
||||
private readonly List<FilePattern> filePatterns = new List<FilePattern>();
|
||||
|
||||
public Layout.SubProject Directories { get; }
|
||||
|
||||
private static string? ReadVariable(string name, string line)
|
||||
{
|
||||
var prefix = name + "=";
|
||||
if (!line.StartsWith(prefix))
|
||||
return null;
|
||||
return line.Substring(prefix.Length).Trim();
|
||||
}
|
||||
|
||||
public LayoutBlock(string[] lines, ref int i)
|
||||
{
|
||||
// first line: #name
|
||||
i++;
|
||||
var trapFolder = ReadVariable("TRAP_FOLDER", lines[i++]);
|
||||
// Don't care about ODASA_DB.
|
||||
ReadVariable("ODASA_DB", lines[i++]);
|
||||
var sourceArchive = ReadVariable("SOURCE_ARCHIVE", lines[i++]);
|
||||
|
||||
Directories = new Layout.SubProject(trapFolder, sourceArchive);
|
||||
// Don't care about ODASA_BUILD_ERROR_DIR.
|
||||
ReadVariable("ODASA_BUILD_ERROR_DIR", lines[i++]);
|
||||
while (i < lines.Length && !lines[i].StartsWith("#"))
|
||||
{
|
||||
filePatterns.Add(new FilePattern(lines[i++]));
|
||||
}
|
||||
}
|
||||
|
||||
public bool Matches(PathTransformer.ITransformedPath path) => FilePattern.Matches(filePatterns, path.Value, out var _);
|
||||
}
|
||||
}
|
||||
@@ -3,6 +3,7 @@ using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using Semmle.Util;
|
||||
using Semmle.Util.Logging;
|
||||
|
||||
namespace Semmle.Extraction
|
||||
{
|
||||
@@ -35,6 +36,20 @@ namespace Semmle.Extraction
|
||||
ITransformedPath WithSuffix(string suffix);
|
||||
|
||||
string DatabaseId { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the name of the trap file for this file.
|
||||
/// </summary>
|
||||
/// <returns>The full filepath of the trap file.</returns>
|
||||
public string GetTrapPath(ILogger logger, TrapWriter.CompressionMode trapCompression) =>
|
||||
TrapWriter.TrapPath(logger, Environment.GetEnvironmentVariable("CODEQL_EXTRACTOR_CSHARP_TRAP_DIR"), this, trapCompression);
|
||||
|
||||
/// <summary>
|
||||
/// Creates a trap writer for this file.
|
||||
/// </summary>
|
||||
/// <returns>A newly created TrapWriter.</returns>
|
||||
public TrapWriter CreateTrapWriter(ILogger logger, TrapWriter.CompressionMode trapCompression, bool discardDuplicates) =>
|
||||
new(logger, this, Environment.GetEnvironmentVariable("CODEQL_EXTRACTOR_CSHARP_TRAP_DIR"), Environment.GetEnvironmentVariable("CODEQL_EXTRACTOR_CSHARP_SOURCE_ARCHIVE_DIR"), trapCompression, discardDuplicates);
|
||||
}
|
||||
|
||||
private struct TransformedPath : ITransformedPath
|
||||
|
||||
@@ -234,9 +234,7 @@ namespace Semmle.Util
|
||||
/// <returns>A new CanonicalPathCache.</returns>
|
||||
public static CanonicalPathCache Create(ILogger logger, int maxCapacity)
|
||||
{
|
||||
var preserveSymlinks =
|
||||
Environment.GetEnvironmentVariable("CODEQL_PRESERVE_SYMLINKS") == "true" ||
|
||||
Environment.GetEnvironmentVariable("SEMMLE_PRESERVE_SYMLINKS") == "true";
|
||||
var preserveSymlinks = Environment.GetEnvironmentVariable("CODEQL_PRESERVE_SYMLINKS") == "true";
|
||||
return Create(logger, maxCapacity, preserveSymlinks ? CanonicalPathCache.Symlinks.Preserve : CanonicalPathCache.Symlinks.Follow);
|
||||
|
||||
}
|
||||
|
||||
@@ -74,7 +74,7 @@ namespace Semmle.Util.Logging
|
||||
}
|
||||
catch (Exception ex) // lgtm[cs/catch-of-all-exceptions]
|
||||
{
|
||||
Console.Error.WriteLine("SEMMLE: Couldn't initialise C# extractor output: " + ex.Message + "\n" + ex.StackTrace);
|
||||
Console.Error.WriteLine("CodeQL: Couldn't initialise C# extractor output: " + ex.Message + "\n" + ex.StackTrace);
|
||||
Console.Error.Flush();
|
||||
throw;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
---
|
||||
category: minorAnalysis
|
||||
---
|
||||
* All deprecated predicates/classes/modules that have been deprecated for over a year have been deleted.
|
||||
15
csharp/ql/lib/change-notes/2022-03-07-legacy-env-vars.md
Normal file
15
csharp/ql/lib/change-notes/2022-03-07-legacy-env-vars.md
Normal file
@@ -0,0 +1,15 @@
|
||||
---
|
||||
category: breaking
|
||||
---
|
||||
* The C# extractor no longer supports the following legacy environment variables:
|
||||
```
|
||||
ODASA_BUILD_ERROR_DIR
|
||||
ODASA_CSHARP_LAYOUT
|
||||
ODASA_SNAPSHOT
|
||||
SEMMLE_DIST
|
||||
SEMMLE_EXTRACTOR_OPTIONS
|
||||
SEMMLE_PLATFORM_TOOLS
|
||||
SEMMLE_PRESERVE_SYMLINKS
|
||||
SOURCE_ARCHIVE
|
||||
TRAP_FOLDER
|
||||
```
|
||||
@@ -23,13 +23,6 @@ class Declaration extends DotNet::Declaration, Element, @cil_declaration {
|
||||
}
|
||||
|
||||
override Declaration getUnboundDeclaration() { result = this }
|
||||
|
||||
/**
|
||||
* DEPRECATED: Use `isUnboundDeclaration()` instead.
|
||||
*
|
||||
* Holds if this declaration is a source declaration.
|
||||
*/
|
||||
deprecated final predicate isSourceDeclaration() { this.isUnboundDeclaration() }
|
||||
}
|
||||
|
||||
private CS::Declaration toCSharpNonTypeParameter(Declaration d) { result.matchesHandle(d) }
|
||||
|
||||
@@ -64,11 +64,6 @@ class Callable extends DotNet::Callable, Parameterizable, ExprOrStmtParent, @cal
|
||||
result = this.getExpressionBody()
|
||||
}
|
||||
|
||||
/**
|
||||
* DEPRECATED: Use `getBody()` instead.
|
||||
*/
|
||||
deprecated final ControlFlowElement getABody() { result = this.getBody() }
|
||||
|
||||
override predicate hasBody() { exists(this.getBody()) }
|
||||
|
||||
/**
|
||||
@@ -151,11 +146,6 @@ class Callable extends DotNet::Callable, Parameterizable, ExprOrStmtParent, @cal
|
||||
not result = this.(Constructor).getInitializer()
|
||||
}
|
||||
|
||||
/**
|
||||
* DEPRECATED: Use `getExpressionBody()` instead.
|
||||
*/
|
||||
deprecated final Expr getAnExpressionBody() { result = this.getExpressionBody() }
|
||||
|
||||
/** Holds if this callable has an expression body. */
|
||||
final predicate hasExpressionBody() { exists(this.getExpressionBody()) }
|
||||
|
||||
|
||||
@@ -12,13 +12,6 @@ class XMLLocatable extends @xmllocatable, TXMLLocatable {
|
||||
/** Gets the source location for this element. */
|
||||
Location getLocation() { xmllocations(this, result) }
|
||||
|
||||
/**
|
||||
* DEPRECATED: Use `getLocation()` instead.
|
||||
*
|
||||
* Gets the source location for this element.
|
||||
*/
|
||||
deprecated Location getALocation() { result = this.getLocation() }
|
||||
|
||||
/**
|
||||
* Holds if this element is at the specified location.
|
||||
* The location spans column `startcolumn` of line `startline` to
|
||||
@@ -83,21 +76,6 @@ class XMLParent extends @xmlparent {
|
||||
/** Gets the number of places in the body of this XML parent where text occurs. */
|
||||
int getNumberOfCharacterSets() { result = count(int pos | xmlChars(_, _, this, pos, _, _)) }
|
||||
|
||||
/**
|
||||
* DEPRECATED: Internal.
|
||||
*
|
||||
* Append the character sequences of this XML parent from left to right, separated by a space,
|
||||
* up to a specified (zero-based) index.
|
||||
*/
|
||||
deprecated string charsSetUpTo(int n) {
|
||||
n = 0 and xmlChars(_, result, this, 0, _, _)
|
||||
or
|
||||
n > 0 and
|
||||
exists(string chars | xmlChars(_, chars, this, n, _, _) |
|
||||
result = this.charsSetUpTo(n - 1) + " " + chars
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the result of appending all the character sequences of this XML parent from
|
||||
* left to right, separated by a space.
|
||||
|
||||
@@ -59,13 +59,6 @@ abstract class AssertMethod extends Method {
|
||||
|
||||
/** Gets the failure type if the assertion fails for argument `i`, if any. */
|
||||
abstract AssertionFailure getAssertionFailure(int i);
|
||||
|
||||
/**
|
||||
* DEPRECATED: Use `getAssertionFailure(_)` instead.
|
||||
*
|
||||
* Gets the exception being thrown if the assertion fails, if any.
|
||||
*/
|
||||
deprecated final Class getExceptionClass() { this.getAssertionFailure(_).isException(result) }
|
||||
}
|
||||
|
||||
/** A Boolean assertion method. */
|
||||
@@ -76,34 +69,6 @@ abstract class BooleanAssertMethod extends AssertMethod {
|
||||
override int getAnAssertionIndex() { result = this.getAnAssertionIndex(_) }
|
||||
}
|
||||
|
||||
/** A positive assertion method. */
|
||||
deprecated class AssertTrueMethod extends AssertMethod {
|
||||
private BooleanAssertMethod m;
|
||||
|
||||
AssertTrueMethod() {
|
||||
this = m and
|
||||
exists(m.getAnAssertionIndex(true))
|
||||
}
|
||||
|
||||
final override int getAnAssertionIndex() { result = m.getAnAssertionIndex() }
|
||||
|
||||
final override AssertionFailure getAssertionFailure(int i) { result = m.getAssertionFailure(i) }
|
||||
}
|
||||
|
||||
/** A negated assertion method. */
|
||||
deprecated class AssertFalseMethod extends AssertMethod {
|
||||
private BooleanAssertMethod m;
|
||||
|
||||
AssertFalseMethod() {
|
||||
this = m and
|
||||
exists(m.getAnAssertionIndex(false))
|
||||
}
|
||||
|
||||
final override int getAnAssertionIndex() { result = m.getAnAssertionIndex() }
|
||||
|
||||
final override AssertionFailure getAssertionFailure(int i) { result = m.getAssertionFailure(i) }
|
||||
}
|
||||
|
||||
/** A nullness assertion method. */
|
||||
abstract class NullnessAssertMethod extends AssertMethod {
|
||||
/**
|
||||
@@ -115,34 +80,6 @@ abstract class NullnessAssertMethod extends AssertMethod {
|
||||
override int getAnAssertionIndex() { result = this.getAnAssertionIndex(_) }
|
||||
}
|
||||
|
||||
/** A `null` assertion method. */
|
||||
deprecated class AssertNullMethod extends AssertMethod {
|
||||
private NullnessAssertMethod m;
|
||||
|
||||
AssertNullMethod() {
|
||||
this = m and
|
||||
exists(m.getAnAssertionIndex(true))
|
||||
}
|
||||
|
||||
final override int getAnAssertionIndex() { result = m.getAnAssertionIndex() }
|
||||
|
||||
final override AssertionFailure getAssertionFailure(int i) { result = m.getAssertionFailure(i) }
|
||||
}
|
||||
|
||||
/** A non-`null` assertion method. */
|
||||
deprecated class AssertNonNullMethod extends AssertMethod {
|
||||
private NullnessAssertMethod m;
|
||||
|
||||
AssertNonNullMethod() {
|
||||
this = m and
|
||||
exists(m.getAnAssertionIndex(false))
|
||||
}
|
||||
|
||||
final override int getAnAssertionIndex() { result = m.getAnAssertionIndex() }
|
||||
|
||||
final override AssertionFailure getAssertionFailure(int i) { result = m.getAssertionFailure(i) }
|
||||
}
|
||||
|
||||
/** An assertion, that is, a call to an assertion method. */
|
||||
class Assertion extends MethodCall {
|
||||
private AssertMethod target;
|
||||
@@ -160,108 +97,6 @@ class Assertion extends MethodCall {
|
||||
result = this.getArgumentForParameter(p)
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* DEPRECATED: Use `getExpr(_)` instead.
|
||||
*
|
||||
* Gets an expression that this assertion pertains to.
|
||||
*/
|
||||
deprecated Expr getExpr() { result = this.getExpr(_) }
|
||||
|
||||
/**
|
||||
* Holds if basic block `succ` is immediately dominated by this assertion.
|
||||
* That is, `succ` can only be reached from the callable entry point by
|
||||
* going via *some* basic block `pred` containing this assertion, and `pred`
|
||||
* is an immediate predecessor of `succ`.
|
||||
*
|
||||
* Moreover, this assertion corresponds to multiple control flow nodes,
|
||||
* which is why
|
||||
*
|
||||
* ```ql
|
||||
* exists(BasicBlock bb |
|
||||
* bb.getANode() = this.getAControlFlowNode() |
|
||||
* bb.immediatelyDominates(succ)
|
||||
* )
|
||||
* ```
|
||||
*
|
||||
* does not work.
|
||||
*/
|
||||
pragma[nomagic]
|
||||
deprecated private predicate immediatelyDominatesBlockSplit(BasicBlock succ) {
|
||||
// Only calculate dominance by explicit recursion for split nodes;
|
||||
// all other nodes can use regular CFG dominance
|
||||
this instanceof SplitControlFlowElement and
|
||||
exists(BasicBlock bb | bb.getANode() = this.getAControlFlowNode() |
|
||||
succ = bb.getASuccessor() and
|
||||
forall(BasicBlock pred | pred = succ.getAPredecessor() and pred != bb |
|
||||
succ.dominates(pred)
|
||||
or
|
||||
// `pred` might be another split of this element
|
||||
pred.getANode().getElement() = this
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
pragma[noinline]
|
||||
deprecated private predicate strictlyDominatesJoinBlockPredecessor(JoinBlock jb, int i) {
|
||||
this.strictlyDominatesSplit(jb.getJoinBlockPredecessor(i))
|
||||
}
|
||||
|
||||
deprecated private predicate strictlyDominatesJoinBlockSplit(JoinBlock jb, int i) {
|
||||
i = -1 and
|
||||
this.strictlyDominatesJoinBlockPredecessor(jb, _)
|
||||
or
|
||||
this.strictlyDominatesJoinBlockSplit(jb, i - 1) and
|
||||
(
|
||||
this.strictlyDominatesJoinBlockPredecessor(jb, i)
|
||||
or
|
||||
this.getAControlFlowNode().getBasicBlock() = jb.getJoinBlockPredecessor(i)
|
||||
)
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
deprecated private predicate strictlyDominatesSplit(BasicBlock bb) {
|
||||
this.immediatelyDominatesBlockSplit(bb)
|
||||
or
|
||||
// Equivalent with
|
||||
//
|
||||
// ```ql
|
||||
// exists(JoinBlockPredecessor pred | pred = bb.getAPredecessor() |
|
||||
// this.strictlyDominatesSplit(pred)
|
||||
// ) and
|
||||
// forall(JoinBlockPredecessor pred | pred = bb.getAPredecessor() |
|
||||
// this.strictlyDominatesSplit(pred)
|
||||
// or
|
||||
// this.getAControlFlowNode().getBasicBlock() = pred
|
||||
// )
|
||||
// ```
|
||||
//
|
||||
// but uses no universal recursion for better performance.
|
||||
exists(int last | last = max(int i | exists(bb.(JoinBlock).getJoinBlockPredecessor(i))) |
|
||||
this.strictlyDominatesJoinBlockSplit(bb, last)
|
||||
)
|
||||
or
|
||||
not bb instanceof JoinBlock and
|
||||
this.strictlyDominatesSplit(bb.getAPredecessor())
|
||||
}
|
||||
|
||||
/**
|
||||
* DEPRECATED: Use `getExpr().controlsBlock()` instead.
|
||||
*
|
||||
* Holds if this assertion strictly dominates basic block `bb`. That is, `bb`
|
||||
* can only be reached from the callable entry point by going via *some* basic
|
||||
* block containing this element.
|
||||
*
|
||||
* This predicate is different from
|
||||
* `this.getAControlFlowNode().getBasicBlock().strictlyDominates(bb)`
|
||||
* in that it takes control flow splitting into account.
|
||||
*/
|
||||
pragma[nomagic]
|
||||
deprecated predicate strictlyDominates(BasicBlock bb) {
|
||||
this.strictlyDominatesSplit(bb)
|
||||
or
|
||||
this.getAControlFlowNode().getBasicBlock().strictlyDominates(bb)
|
||||
}
|
||||
}
|
||||
|
||||
/** A trivially failing assertion, for example `Debug.Assert(false)`. */
|
||||
@@ -551,16 +386,6 @@ class ForwarderBooleanAssertMethod extends BooleanAssertMethod {
|
||||
}
|
||||
}
|
||||
|
||||
/** A method that forwards to a positive assertion method. */
|
||||
deprecated class ForwarderAssertTrueMethod extends ForwarderBooleanAssertMethod {
|
||||
ForwarderAssertTrueMethod() { exists(this.getAnAssertionIndex(true)) }
|
||||
}
|
||||
|
||||
/** A method that forwards to a negated assertion method. */
|
||||
deprecated class ForwarderAssertFalseMethod extends ForwarderBooleanAssertMethod {
|
||||
ForwarderAssertFalseMethod() { exists(this.getAnAssertionIndex(false)) }
|
||||
}
|
||||
|
||||
/** A method that forwards to a nullness assertion method. */
|
||||
class ForwarderNullnessAssertMethod extends NullnessAssertMethod {
|
||||
private ForwarderAssertMethod forwarder;
|
||||
@@ -580,15 +405,5 @@ class ForwarderNullnessAssertMethod extends NullnessAssertMethod {
|
||||
}
|
||||
}
|
||||
|
||||
/** A method that forwards to a `null` assertion method. */
|
||||
deprecated class ForwarderAssertNullMethod extends ForwarderNullnessAssertMethod {
|
||||
ForwarderAssertNullMethod() { exists(this.getAnAssertionIndex(true)) }
|
||||
}
|
||||
|
||||
/** A method that forwards to a non-`null` assertion method. */
|
||||
deprecated class ForwarderAssertNonNullMethod extends ForwarderNullnessAssertMethod {
|
||||
ForwarderAssertNonNullMethod() { exists(this.getAnAssertionIndex(false)) }
|
||||
}
|
||||
|
||||
/** Holds if expression `e` appears in an assertion. */
|
||||
predicate isExprInAssertion(Expr e) { e = any(Assertion a).getExpr(_).getAChildExpr*() }
|
||||
|
||||
@@ -227,35 +227,4 @@ class ControlFlowElement extends ExprOrStmtParent, @control_flow_element {
|
||||
cb.getLastNode() = this.getAControlFlowNode() and
|
||||
cb.controls(controlled, s)
|
||||
}
|
||||
|
||||
/** DEPRECATED: Use `controlsBlock/3` instead. */
|
||||
deprecated predicate controlsBlock(BasicBlock controlled, ConditionalSuccessor s) {
|
||||
this.controlsBlock(controlled, s, _)
|
||||
}
|
||||
|
||||
/**
|
||||
* DEPRECATED.
|
||||
*
|
||||
* Holds if control flow element `controlled` is controlled by this control flow
|
||||
* element with conditional value `s`. That is, `controlled` can only be reached
|
||||
* from the callable entry point by going via the `s` edge out of this element.
|
||||
*
|
||||
* This predicate is different from
|
||||
*
|
||||
* ```ql
|
||||
* exists(ConditionBlock cb |
|
||||
* cb.getLastNode() = this.getAControlFlowNode() |
|
||||
* cb.controls(controlled.getAControlFlowNode().getBasicBlock(), s)
|
||||
* )
|
||||
* ```
|
||||
*
|
||||
* as control flow splitting is taken into account.
|
||||
*/
|
||||
// potentially very large predicate, so must be inlined
|
||||
pragma[inline]
|
||||
deprecated predicate controlsElement(ControlFlowElement controlled, ConditionalSuccessor s) {
|
||||
forex(BasicBlock bb | bb = controlled.getAControlFlowNode().getBasicBlock() |
|
||||
this.controlsBlock(bb, s)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,9 +26,6 @@ private newtype TSuccessorType =
|
||||
class SuccessorType extends TSuccessorType {
|
||||
/** Gets a textual representation of successor type. */
|
||||
string toString() { none() }
|
||||
|
||||
/** Holds if this successor type matches completion `c`. */
|
||||
deprecated predicate matchesCompletion(Completion c) { this = c.getAMatchingSuccessorType() }
|
||||
}
|
||||
|
||||
/** Provides different types of control flow successor types. */
|
||||
|
||||
@@ -427,11 +427,6 @@ module Ssa {
|
||||
not result instanceof PhiNode
|
||||
}
|
||||
|
||||
/**
|
||||
* DEPRECATED: Use `definesAt/3` instead.
|
||||
*/
|
||||
deprecated predicate definesAt(ControlFlow::BasicBlock bb, int i) { this.definesAt(_, bb, i) }
|
||||
|
||||
/**
|
||||
* Gets the syntax element associated with this SSA definition, if any.
|
||||
* This is either an expression, for example `x = 0`, a parameter, or a
|
||||
@@ -655,14 +650,6 @@ module Ssa {
|
||||
override Location getLocation() { result = this.getQualifierDefinition().getLocation() }
|
||||
}
|
||||
|
||||
/**
|
||||
* An SSA definition that has no actual semantics, but simply serves to
|
||||
* merge or filter data flow.
|
||||
*
|
||||
* Phi nodes are the canonical (and currently only) example.
|
||||
*/
|
||||
deprecated class PseudoDefinition = PhiNode;
|
||||
|
||||
/**
|
||||
* An SSA phi node, that is, a pseudo definition for a variable at a point
|
||||
* in the flow graph where otherwise two or more definitions for the variable
|
||||
|
||||
@@ -204,12 +204,6 @@ class Content extends TContent {
|
||||
|
||||
/** Gets the location of this content. */
|
||||
Location getLocation() { none() }
|
||||
|
||||
/** Gets the type of the object containing this content. */
|
||||
deprecated Gvn::GvnType getContainerType() { none() }
|
||||
|
||||
/** Gets the type of this content. */
|
||||
deprecated Gvn::GvnType getType() { none() }
|
||||
}
|
||||
|
||||
/** A reference to a field. */
|
||||
@@ -224,12 +218,6 @@ class FieldContent extends Content, TFieldContent {
|
||||
override string toString() { result = "field " + f.getName() }
|
||||
|
||||
override Location getLocation() { result = f.getLocation() }
|
||||
|
||||
deprecated override Gvn::GvnType getContainerType() {
|
||||
result = Gvn::getGlobalValueNumber(f.getDeclaringType())
|
||||
}
|
||||
|
||||
deprecated override Gvn::GvnType getType() { result = Gvn::getGlobalValueNumber(f.getType()) }
|
||||
}
|
||||
|
||||
/** A reference to a synthetic field. */
|
||||
@@ -256,12 +244,6 @@ class PropertyContent extends Content, TPropertyContent {
|
||||
override string toString() { result = "property " + p.getName() }
|
||||
|
||||
override Location getLocation() { result = p.getLocation() }
|
||||
|
||||
deprecated override Gvn::GvnType getContainerType() {
|
||||
result = Gvn::getGlobalValueNumber(p.getDeclaringType())
|
||||
}
|
||||
|
||||
deprecated override Gvn::GvnType getType() { result = Gvn::getGlobalValueNumber(p.getType()) }
|
||||
}
|
||||
|
||||
/** A reference to an element in a collection. */
|
||||
|
||||
@@ -31,8 +31,6 @@ predicate defaultTaintSanitizerGuard(DataFlow::BarrierGuard guard) { none() }
|
||||
bindingset[node]
|
||||
predicate defaultImplicitTaintRead(DataFlow::Node node, DataFlow::Content c) { none() }
|
||||
|
||||
deprecated predicate localAdditionalTaintStep = defaultAdditionalTaintStep/2;
|
||||
|
||||
private CIL::DataFlowNode asCilDataFlowNode(DataFlow::Node node) {
|
||||
result = node.asParameter() or
|
||||
result = node.asExpr()
|
||||
|
||||
@@ -170,40 +170,6 @@ class InvalidFormatString extends StringLiteral {
|
||||
}
|
||||
}
|
||||
|
||||
/** Provides a dataflow configuration for format strings. */
|
||||
deprecated module FormatFlow {
|
||||
private import semmle.code.csharp.dataflow.DataFlow
|
||||
|
||||
private class FormatConfiguration extends DataFlow2::Configuration {
|
||||
FormatConfiguration() { this = "format" }
|
||||
|
||||
override predicate isSource(DataFlow::Node n) { n.asExpr() instanceof StringLiteral }
|
||||
|
||||
override predicate isSink(DataFlow::Node n) {
|
||||
exists(FormatCall c | n.asExpr() = c.getFormatExpr())
|
||||
}
|
||||
}
|
||||
|
||||
deprecated query predicate nodes = DataFlow2::PathGraph::nodes/3;
|
||||
|
||||
deprecated query predicate edges = DataFlow2::PathGraph::edges/2;
|
||||
|
||||
deprecated class PathNode = DataFlow2::PathNode;
|
||||
|
||||
/**
|
||||
* Holds if there is flow from string literal `lit` to the format string in
|
||||
* `call`. `litNode` and `formatNode` are the corresponding data-flow path
|
||||
* nodes.
|
||||
*/
|
||||
deprecated predicate hasFlowPath(
|
||||
StringLiteral lit, PathNode litNode, FormatCall call, PathNode formatNode
|
||||
) {
|
||||
litNode.getNode().asExpr() = lit and
|
||||
formatNode.getNode().asExpr() = call.getFormatExpr() and
|
||||
any(FormatConfiguration conf).hasFlowPath(litNode, formatNode)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A method call to a method that formats a string, for example a call
|
||||
* to `string.Format()`.
|
||||
@@ -229,14 +195,6 @@ class FormatCall extends MethodCall {
|
||||
this.getArgument(this.getFirstArgument()).getType() instanceof ArrayType
|
||||
}
|
||||
|
||||
/**
|
||||
* DEPRECATED: Use `FormatFlow::hasFlowPath()` instead.
|
||||
*
|
||||
* Gets a format string. Global data flow analysis is applied to retrieve all
|
||||
* sources that can reach this method call.
|
||||
*/
|
||||
deprecated StringLiteral getAFormatSource() { FormatFlow::hasFlowPath(result, _, this, _) }
|
||||
|
||||
/**
|
||||
* Gets the number of supplied arguments (excluding the format string and format
|
||||
* provider). Does not return a value if the arguments are supplied in an array,
|
||||
@@ -255,11 +213,4 @@ class FormatCall extends MethodCall {
|
||||
index = this.getASuppliedArgument() and
|
||||
result = this.getArgument(this.getFirstArgument() + index)
|
||||
}
|
||||
|
||||
/** Gets a supplied argument that is not used in the format string `src`. */
|
||||
deprecated int getAnUnusedArgument(ValidFormatString src) {
|
||||
result = this.getASuppliedArgument() and
|
||||
FormatFlow::hasFlowPath(src, _, this, _) and
|
||||
not result = src.getAnInsert()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,13 +21,6 @@ class Declaration extends NamedElement, @dotnet_declaration {
|
||||
/** Gets the type containing this declaration, if any. */
|
||||
Type getDeclaringType() { none() }
|
||||
|
||||
/**
|
||||
* DEPRECATED: Use `getUnboundDeclaration()` instaed.
|
||||
*
|
||||
* Gets the unbound version of this declaration.
|
||||
*/
|
||||
deprecated final Declaration getSourceDeclaration() { result = this.getUnboundDeclaration() }
|
||||
|
||||
/**
|
||||
* Gets the unbound version of this declaration, that is, the declaration where
|
||||
* all type arguments have been removed. For example, in
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
---
|
||||
category: minorAnalysis
|
||||
---
|
||||
* All deprecated predicates/classes/modules that have been deprecated for over a year have been deleted.
|
||||
@@ -0,0 +1,8 @@
|
||||
---
|
||||
category: minorAnalysis
|
||||
---
|
||||
* Add new predicate `CompileTimeConstantExpr.getStringifiedValue` which attempts to compute the
|
||||
`String.valueOf` string rendering of a constant expression. This predicate is now used to
|
||||
compute the string value of an `AddExpr` that has the type `String`. `getStringValue` now
|
||||
once again only works for expressions of type `String`, and specifically does not work for
|
||||
character literals.
|
||||
@@ -161,6 +161,38 @@ class CompileTimeConstantExpr extends Expr {
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the stringified value of this expression, where possible.
|
||||
*
|
||||
* The stringified version of a compile-time constant expression is the equivalent to
|
||||
* the result of calling `String.valueOf(expr)` on the expression.
|
||||
*
|
||||
* Note that this does not handle the following cases:
|
||||
*
|
||||
* - mathematical computations of type `long`, `float`, or `double`.
|
||||
*/
|
||||
pragma[nomagic]
|
||||
string getStringifiedValue() {
|
||||
result = this.getStringValue()
|
||||
or
|
||||
result = this.(Literal).getValue()
|
||||
or
|
||||
result = this.getBooleanValue().toString()
|
||||
or
|
||||
result = this.getIntValue().toString()
|
||||
or
|
||||
// Ternary conditional, with compile-time constant condition.
|
||||
exists(ConditionalExpr ce, boolean condition |
|
||||
ce = this and
|
||||
condition = ce.getCondition().(CompileTimeConstantExpr).getBooleanValue() and
|
||||
result = ce.getBranchExpr(condition).(CompileTimeConstantExpr).getStringifiedValue()
|
||||
)
|
||||
or
|
||||
exists(Variable v | this = v.getAnAccess() |
|
||||
result = v.getInitializer().(CompileTimeConstantExpr).getStringifiedValue()
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the string value of this expression, where possible.
|
||||
*/
|
||||
@@ -168,11 +200,11 @@ class CompileTimeConstantExpr extends Expr {
|
||||
string getStringValue() {
|
||||
result = this.(StringLiteral).getValue()
|
||||
or
|
||||
result = this.(CharacterLiteral).getValue()
|
||||
or
|
||||
this.getType() instanceof TypeString and // When the expression type is `String`
|
||||
result =
|
||||
this.(AddExpr).getLeftOperand().(CompileTimeConstantExpr).getStringValue() +
|
||||
this.(AddExpr).getRightOperand().(CompileTimeConstantExpr).getStringValue()
|
||||
// Then the resultant string is the addition of both operands stringified value, regardless of type.
|
||||
this.(AddExpr).getLeftOperand().(CompileTimeConstantExpr).getStringifiedValue() +
|
||||
this.(AddExpr).getRightOperand().(CompileTimeConstantExpr).getStringifiedValue()
|
||||
or
|
||||
// Ternary conditional, with compile-time constant condition.
|
||||
exists(ConditionalExpr ce, boolean condition |
|
||||
|
||||
@@ -82,12 +82,6 @@ class BlockStmt extends Stmt, @block {
|
||||
override string getAPrimaryQlClass() { result = "BlockStmt" }
|
||||
}
|
||||
|
||||
/**
|
||||
* DEPRECATED: This is now called `BlockStmt` to avoid confusion with
|
||||
* `BasicBlock`.
|
||||
*/
|
||||
deprecated class Block = BlockStmt;
|
||||
|
||||
/** A block with only a single statement. */
|
||||
class SingletonBlock extends BlockStmt {
|
||||
SingletonBlock() { this.getNumStmt() = 1 }
|
||||
@@ -103,14 +97,6 @@ class SingletonBlock extends BlockStmt {
|
||||
abstract class ConditionalStmt extends Stmt {
|
||||
/** Gets the boolean condition of this conditional statement. */
|
||||
abstract Expr getCondition();
|
||||
|
||||
/**
|
||||
* Gets the statement that is executed whenever the condition
|
||||
* of this branch statement evaluates to `true`.
|
||||
*
|
||||
* DEPRECATED: use `ConditionNode.getATrueSuccessor()` instead.
|
||||
*/
|
||||
abstract deprecated Stmt getTrueSuccessor();
|
||||
}
|
||||
|
||||
/** An `if` statement. */
|
||||
@@ -121,12 +107,6 @@ class IfStmt extends ConditionalStmt, @ifstmt {
|
||||
/** Gets the `then` branch of this `if` statement. */
|
||||
Stmt getThen() { result.isNthChildOf(this, 1) }
|
||||
|
||||
/**
|
||||
* Gets the statement that is executed whenever the condition
|
||||
* of this branch statement evaluates to `true`.
|
||||
*/
|
||||
deprecated override Stmt getTrueSuccessor() { result = this.getThen() }
|
||||
|
||||
/** Gets the `else` branch of this `if` statement. */
|
||||
Stmt getElse() { result.isNthChildOf(this, 2) }
|
||||
|
||||
@@ -174,12 +154,6 @@ class ForStmt extends ConditionalStmt, @forstmt {
|
||||
/** Gets the body of this `for` loop. */
|
||||
Stmt getStmt() { result.getParent() = this and result.getIndex() = 2 }
|
||||
|
||||
/**
|
||||
* Gets the statement that is executed whenever the condition
|
||||
* of this branch statement evaluates to true.
|
||||
*/
|
||||
deprecated override Stmt getTrueSuccessor() { result = this.getStmt() }
|
||||
|
||||
/**
|
||||
* Gets a variable that is used as an iteration variable: it is defined,
|
||||
* updated or tested in the head of the `for` statement.
|
||||
@@ -238,12 +212,6 @@ class WhileStmt extends ConditionalStmt, @whilestmt {
|
||||
/** Gets the body of this `while` loop. */
|
||||
Stmt getStmt() { result.getParent() = this }
|
||||
|
||||
/**
|
||||
* Gets the statement that is executed whenever the condition
|
||||
* of this branch statement evaluates to true.
|
||||
*/
|
||||
deprecated override Stmt getTrueSuccessor() { result = this.getStmt() }
|
||||
|
||||
override string pp() { result = "while (...) " + this.getStmt().pp() }
|
||||
|
||||
override string toString() { result = "while (...)" }
|
||||
@@ -261,12 +229,6 @@ class DoStmt extends ConditionalStmt, @dostmt {
|
||||
/** Gets the body of this `do` loop. */
|
||||
Stmt getStmt() { result.getParent() = this }
|
||||
|
||||
/**
|
||||
* Gets the statement that is executed whenever the condition
|
||||
* of this branch statement evaluates to `true`.
|
||||
*/
|
||||
deprecated override Stmt getTrueSuccessor() { result = this.getStmt() }
|
||||
|
||||
override string pp() { result = "do " + this.getStmt().pp() + " while (...)" }
|
||||
|
||||
override string toString() { result = "do ... while (...)" }
|
||||
|
||||
@@ -244,34 +244,6 @@ string getSecureAlgorithmRegex() {
|
||||
result = algorithmRegex(secureAlgorithmString(max(int i | exists(rankedSecureAlgorithm(i)))))
|
||||
}
|
||||
|
||||
/**
|
||||
* DEPRECATED: Terminology has been updated. Use `getAnInsecureAlgorithmName()`
|
||||
* instead.
|
||||
*/
|
||||
deprecated string algorithmBlacklist() { result = getAnInsecureAlgorithmName() }
|
||||
|
||||
/**
|
||||
* DEPRECATED: Terminology has been updated. Use
|
||||
* `getAnInsecureHashAlgorithmName()` instead.
|
||||
*/
|
||||
deprecated string hashAlgorithmBlacklist() { result = getAnInsecureHashAlgorithmName() }
|
||||
|
||||
/**
|
||||
* DEPRECATED: Terminology has been updated. Use `getInsecureAlgorithmRegex()` instead.
|
||||
*/
|
||||
deprecated string algorithmBlacklistRegex() { result = getInsecureAlgorithmRegex() }
|
||||
|
||||
/**
|
||||
* DEPRECATED: Terminology has been updated. Use `getASecureAlgorithmName()`
|
||||
* instead.
|
||||
*/
|
||||
deprecated string algorithmWhitelist() { result = getASecureAlgorithmName() }
|
||||
|
||||
/**
|
||||
* DEPRECATED: Terminology has been updated. Use `getSecureAlgorithmRegex()` instead.
|
||||
*/
|
||||
deprecated string algorithmWhitelistRegex() { result = getSecureAlgorithmRegex() }
|
||||
|
||||
/**
|
||||
* Any use of a cryptographic element that specifies an encryption
|
||||
* algorithm. For example, methods returning ciphers, decryption methods,
|
||||
|
||||
@@ -12,13 +12,6 @@ class XMLLocatable extends @xmllocatable, TXMLLocatable {
|
||||
/** Gets the source location for this element. */
|
||||
Location getLocation() { xmllocations(this, result) }
|
||||
|
||||
/**
|
||||
* DEPRECATED: Use `getLocation()` instead.
|
||||
*
|
||||
* Gets the source location for this element.
|
||||
*/
|
||||
deprecated Location getALocation() { result = this.getLocation() }
|
||||
|
||||
/**
|
||||
* Holds if this element is at the specified location.
|
||||
* The location spans column `startcolumn` of line `startline` to
|
||||
@@ -83,21 +76,6 @@ class XMLParent extends @xmlparent {
|
||||
/** Gets the number of places in the body of this XML parent where text occurs. */
|
||||
int getNumberOfCharacterSets() { result = count(int pos | xmlChars(_, _, this, pos, _, _)) }
|
||||
|
||||
/**
|
||||
* DEPRECATED: Internal.
|
||||
*
|
||||
* Append the character sequences of this XML parent from left to right, separated by a space,
|
||||
* up to a specified (zero-based) index.
|
||||
*/
|
||||
deprecated string charsSetUpTo(int n) {
|
||||
n = 0 and xmlChars(_, result, this, 0, _, _)
|
||||
or
|
||||
n > 0 and
|
||||
exists(string chars | xmlChars(_, chars, this, n, _, _) |
|
||||
result = this.charsSetUpTo(n - 1) + " " + chars
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the result of appending all the character sequences of this XML parent from
|
||||
* left to right, separated by a space.
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import semmle.code.java.Expr
|
||||
import java
|
||||
|
||||
from CompileTimeConstantExpr constant, RefType tpe
|
||||
where
|
||||
|
||||
@@ -133,6 +133,151 @@ constants/Initializers.java:
|
||||
# 37| 0: [AssignExpr] ...=...
|
||||
# 37| 0: [VarAccess] f
|
||||
# 37| 1: [IntegerLiteral] 42
|
||||
constants/Stringified.java:
|
||||
# 0| [CompilationUnit] Stringified
|
||||
# 3| 1: [Class] Stringified
|
||||
# 4| 2: [Method] stringified
|
||||
# 4| 3: [TypeAccess] void
|
||||
#-----| 4: (Parameters)
|
||||
# 4| 0: [Parameter] notConstant
|
||||
# 4| 0: [TypeAccess] String
|
||||
# 4| 5: [BlockStmt] { ... }
|
||||
# 5| 0: [LocalVariableDeclStmt] var ...;
|
||||
# 5| 0: [TypeAccess] String
|
||||
# 5| 1: [LocalVariableDeclExpr] withNotConstant
|
||||
# 5| 0: [AddExpr] ... + ...
|
||||
# 5| 0: [StringLiteral] "a"
|
||||
# 5| 1: [VarAccess] notConstant
|
||||
# 6| 1: [LocalVariableDeclStmt] var ...;
|
||||
# 6| 0: [TypeAccess] String
|
||||
# 6| 1: [LocalVariableDeclExpr] string
|
||||
# 6| 0: [StringLiteral] "a" + "b"
|
||||
# 7| 2: [LocalVariableDeclStmt] var ...;
|
||||
# 7| 0: [TypeAccess] String
|
||||
# 7| 1: [LocalVariableDeclExpr] stringWithChar
|
||||
# 7| 0: [AddExpr] ... + ...
|
||||
# 7| 0: [StringLiteral] "ab"
|
||||
# 7| 1: [CharacterLiteral] 'c'
|
||||
# 8| 3: [LocalVariableDeclStmt] var ...;
|
||||
# 8| 0: [TypeAccess] String
|
||||
# 8| 1: [LocalVariableDeclExpr] stringWithBool
|
||||
# 8| 0: [AddExpr] ... + ...
|
||||
# 8| 0: [StringLiteral] "ab"
|
||||
# 8| 1: [BooleanLiteral] true
|
||||
# 9| 4: [LocalVariableDeclStmt] var ...;
|
||||
# 9| 0: [TypeAccess] String
|
||||
# 9| 1: [LocalVariableDeclExpr] stringWithInt
|
||||
# 9| 0: [AddExpr] ... + ...
|
||||
# 9| 0: [StringLiteral] "ab"
|
||||
# 9| 1: [IntegerLiteral] 42
|
||||
# 10| 5: [LocalVariableDeclStmt] var ...;
|
||||
# 10| 0: [TypeAccess] String
|
||||
# 10| 1: [LocalVariableDeclExpr] stringWithDouble
|
||||
# 10| 0: [AddExpr] ... + ...
|
||||
# 10| 0: [StringLiteral] "ab"
|
||||
# 10| 1: [DoubleLiteral] 43.0
|
||||
# 11| 6: [LocalVariableDeclStmt] var ...;
|
||||
# 11| 0: [TypeAccess] String
|
||||
# 11| 1: [LocalVariableDeclExpr] stringWithFloat
|
||||
# 11| 0: [AddExpr] ... + ...
|
||||
# 11| 0: [StringLiteral] "ab"
|
||||
# 11| 1: [FloatingPointLiteral] 44.0f
|
||||
# 12| 7: [LocalVariableDeclStmt] var ...;
|
||||
# 12| 0: [TypeAccess] String
|
||||
# 12| 1: [LocalVariableDeclExpr] stringWithLong
|
||||
# 12| 0: [AddExpr] ... + ...
|
||||
# 12| 0: [StringLiteral] "ab"
|
||||
# 12| 1: [LongLiteral] 45L
|
||||
# 13| 8: [LocalVariableDeclStmt] var ...;
|
||||
# 13| 0: [TypeAccess] String
|
||||
# 13| 1: [LocalVariableDeclExpr] stringWithShort
|
||||
# 13| 0: [AddExpr] ... + ...
|
||||
# 13| 0: [StringLiteral] "ab"
|
||||
# 13| 1: [CastExpr] (...)...
|
||||
# 13| 0: [TypeAccess] short
|
||||
# 13| 1: [IntegerLiteral] 46
|
||||
# 14| 9: [LocalVariableDeclStmt] var ...;
|
||||
# 14| 0: [TypeAccess] String
|
||||
# 14| 1: [LocalVariableDeclExpr] stringWithByte
|
||||
# 14| 0: [AddExpr] ... + ...
|
||||
# 14| 0: [StringLiteral] "ab"
|
||||
# 14| 1: [CastExpr] (...)...
|
||||
# 14| 0: [TypeAccess] byte
|
||||
# 14| 1: [IntegerLiteral] 47
|
||||
# 15| 10: [LocalVariableDeclStmt] var ...;
|
||||
# 15| 0: [TypeAccess] String
|
||||
# 15| 1: [LocalVariableDeclExpr] charWithString
|
||||
# 15| 0: [AddExpr] ... + ...
|
||||
# 15| 0: [CharacterLiteral] 'a'
|
||||
# 15| 1: [StringLiteral] "bc"
|
||||
# 16| 11: [LocalVariableDeclStmt] var ...;
|
||||
# 16| 0: [TypeAccess] String
|
||||
# 16| 1: [LocalVariableDeclExpr] boolWithString
|
||||
# 16| 0: [AddExpr] ... + ...
|
||||
# 16| 0: [BooleanLiteral] true
|
||||
# 16| 1: [StringLiteral] "bc"
|
||||
# 17| 12: [LocalVariableDeclStmt] var ...;
|
||||
# 17| 0: [TypeAccess] String
|
||||
# 17| 1: [LocalVariableDeclExpr] intWithString
|
||||
# 17| 0: [AddExpr] ... + ...
|
||||
# 17| 0: [IntegerLiteral] 42
|
||||
# 17| 1: [StringLiteral] "bc"
|
||||
# 18| 13: [LocalVariableDeclStmt] var ...;
|
||||
# 18| 0: [TypeAccess] String
|
||||
# 18| 1: [LocalVariableDeclExpr] doubleWithString
|
||||
# 18| 0: [AddExpr] ... + ...
|
||||
# 18| 0: [DoubleLiteral] 43.0
|
||||
# 18| 1: [StringLiteral] "bc"
|
||||
# 19| 14: [LocalVariableDeclStmt] var ...;
|
||||
# 19| 0: [TypeAccess] String
|
||||
# 19| 1: [LocalVariableDeclExpr] floatWithString
|
||||
# 19| 0: [AddExpr] ... + ...
|
||||
# 19| 0: [FloatingPointLiteral] 44.0f
|
||||
# 19| 1: [StringLiteral] "bc"
|
||||
# 20| 15: [LocalVariableDeclStmt] var ...;
|
||||
# 20| 0: [TypeAccess] String
|
||||
# 20| 1: [LocalVariableDeclExpr] longWithString
|
||||
# 20| 0: [AddExpr] ... + ...
|
||||
# 20| 0: [LongLiteral] 45L
|
||||
# 20| 1: [StringLiteral] "bc"
|
||||
# 21| 16: [LocalVariableDeclStmt] var ...;
|
||||
# 21| 0: [TypeAccess] String
|
||||
# 21| 1: [LocalVariableDeclExpr] shortWithString
|
||||
# 21| 0: [AddExpr] ... + ...
|
||||
# 21| 0: [CastExpr] (...)...
|
||||
# 21| 0: [TypeAccess] short
|
||||
# 21| 1: [IntegerLiteral] 46
|
||||
# 21| 1: [StringLiteral] "bc"
|
||||
# 22| 17: [LocalVariableDeclStmt] var ...;
|
||||
# 22| 0: [TypeAccess] String
|
||||
# 22| 1: [LocalVariableDeclExpr] byteWithString
|
||||
# 22| 0: [AddExpr] ... + ...
|
||||
# 22| 0: [CastExpr] (...)...
|
||||
# 22| 0: [TypeAccess] byte
|
||||
# 22| 1: [IntegerLiteral] 47
|
||||
# 22| 1: [StringLiteral] "bc"
|
||||
# 24| 18: [LocalVariableDeclStmt] var ...;
|
||||
# 24| 0: [TypeAccess] String
|
||||
# 24| 1: [LocalVariableDeclExpr] stringWithExponent
|
||||
# 24| 0: [AddExpr] ... + ...
|
||||
# 24| 0: [StringLiteral] "a"
|
||||
# 24| 1: [DoubleLiteral] 10e1
|
||||
# 25| 19: [LocalVariableDeclStmt] var ...;
|
||||
# 25| 0: [TypeAccess] String
|
||||
# 25| 1: [LocalVariableDeclExpr] stringWithBooleanOr
|
||||
# 25| 0: [AddExpr] ... + ...
|
||||
# 25| 0: [StringLiteral] "a"
|
||||
# 25| 1: [OrLogicalExpr] ... || ...
|
||||
# 25| 0: [BooleanLiteral] true
|
||||
# 25| 1: [BooleanLiteral] false
|
||||
# 26| 20: [LocalVariableDeclStmt] var ...;
|
||||
# 26| 0: [TypeAccess] String
|
||||
# 26| 1: [LocalVariableDeclExpr] stringWithIntDivide
|
||||
# 26| 0: [AddExpr] ... + ...
|
||||
# 26| 0: [StringLiteral] "a"
|
||||
# 26| 1: [DivExpr] ... / ...
|
||||
# 26| 0: [IntegerLiteral] 168
|
||||
# 26| 1: [IntegerLiteral] 4
|
||||
constants/Values.java:
|
||||
# 0| [CompilationUnit] Values
|
||||
# 4| 1: [Class] Values
|
||||
@@ -526,3 +671,9 @@ constants/Values.java:
|
||||
# 92| 0: [AddExpr] ... + ...
|
||||
# 92| 0: [StringLiteral] "ab"
|
||||
# 92| 1: [CharacterLiteral] 'c'
|
||||
# 94| 70: [LocalVariableDeclStmt] var ...;
|
||||
# 94| 0: [TypeAccess] int
|
||||
# 94| 1: [LocalVariableDeclExpr] charWithChar
|
||||
# 94| 0: [AddExpr] ... + ...
|
||||
# 94| 0: [CharacterLiteral] 'a'
|
||||
# 94| 1: [CharacterLiteral] 'b'
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
package constants;
|
||||
|
||||
public class Stringified {
|
||||
void stringified(final String notConstant) {
|
||||
String withNotConstant = "a" + notConstant;
|
||||
String string = "a" + "b"; //ab
|
||||
String stringWithChar = "ab" + 'c'; //abc
|
||||
String stringWithBool = "ab" + true; //abtrue
|
||||
String stringWithInt = "ab" + 42; //ab42
|
||||
String stringWithDouble = "ab" + 43.0; //ab43.0
|
||||
String stringWithFloat = "ab" + 44.0f; //ab44.0
|
||||
String stringWithLong = "ab" + 45L; //ab45
|
||||
String stringWithShort = "ab" + (short) 46; //ab46
|
||||
String stringWithByte = "ab" + (byte) 47; //ab47
|
||||
String charWithString = 'a' + "bc"; //abc
|
||||
String boolWithString = true + "bc"; //truebc
|
||||
String intWithString = 42 + "bc"; //42bc
|
||||
String doubleWithString = 43.0 + "bc"; //43.0bc
|
||||
String floatWithString = 44.0f + "bc"; //44.0bc
|
||||
String longWithString = 45L + "bc"; //45bc
|
||||
String shortWithString = (short) 46 + "bc"; //46bc
|
||||
String byteWithString = (byte) 47 + "bc"; //47bc
|
||||
|
||||
String stringWithExponent = "a" + 10e1; //a100
|
||||
String stringWithBooleanOr = "a" + (true || false); //atrue
|
||||
String stringWithIntDivide = "a" + (168 / 4); //a42
|
||||
}
|
||||
}
|
||||
@@ -90,5 +90,7 @@ class Values {
|
||||
int var_nonfinald_local = var_field; //Not constant
|
||||
String concatenatedString = "a" + "b"; //ab
|
||||
String concatenatedChar = "ab" + 'c'; //abc
|
||||
|
||||
int charWithChar = 'a' + 'b'; //195
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import semmle.code.java.Variable
|
||||
import java
|
||||
|
||||
from Variable v, CompileTimeConstantExpr init, RefType enclosing, boolean constant
|
||||
where
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import semmle.code.java.Variable
|
||||
import java
|
||||
|
||||
from Variable v, Expr init, RefType enclosing
|
||||
where
|
||||
|
||||
@@ -37,3 +37,4 @@
|
||||
| constants/Values.java:86:25:86:35 | final_field | 42 |
|
||||
| constants/Values.java:87:33:87:34 | 42 | 42 |
|
||||
| constants/Values.java:88:25:88:35 | final_local | 42 |
|
||||
| constants/Values.java:94:28:94:36 | ... + ... | 195 |
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user