mirror of
https://github.com/github/codeql.git
synced 2026-04-28 10:15:14 +02:00
Python: Autoformat everything using qlformat.
Will need subsequent PRs fixing up test failures (due to deprecated methods moving around), but other than that everything should be straight-forward.
This commit is contained in:
288
python/ql/src/external/CodeDuplication.qll
vendored
288
python/ql/src/external/CodeDuplication.qll
vendored
@@ -13,80 +13,80 @@ private string relativePath(File file) { result = file.getRelativePath().replace
|
||||
*/
|
||||
pragma[noinline, nomagic]
|
||||
private predicate tokenLocation(File file, int sl, int sc, int ec, int el, Copy copy, int index) {
|
||||
file = copy.sourceFile() and
|
||||
tokens(copy, index, sl, sc, ec, el)
|
||||
file = copy.sourceFile() and
|
||||
tokens(copy, index, sl, sc, ec, el)
|
||||
}
|
||||
|
||||
/** A token block used for detection of duplicate and similar code. */
|
||||
class Copy extends @duplication_or_similarity {
|
||||
private int lastToken() { result = max(int i | tokens(this, i, _, _, _, _) | i) }
|
||||
private int lastToken() { result = max(int i | tokens(this, i, _, _, _, _) | i) }
|
||||
|
||||
/** Gets the index of the token in this block starting at the location `loc`, if any. */
|
||||
int tokenStartingAt(Location loc) {
|
||||
tokenLocation(loc.getFile(), loc.getStartLine(), loc.getStartColumn(), _, _, this, result)
|
||||
}
|
||||
/** Gets the index of the token in this block starting at the location `loc`, if any. */
|
||||
int tokenStartingAt(Location loc) {
|
||||
tokenLocation(loc.getFile(), loc.getStartLine(), loc.getStartColumn(), _, _, this, result)
|
||||
}
|
||||
|
||||
/** Gets the index of the token in this block ending at the location `loc`, if any. */
|
||||
int tokenEndingAt(Location loc) {
|
||||
tokenLocation(loc.getFile(), _, _, loc.getEndLine(), loc.getEndColumn(), this, result)
|
||||
}
|
||||
/** Gets the index of the token in this block ending at the location `loc`, if any. */
|
||||
int tokenEndingAt(Location loc) {
|
||||
tokenLocation(loc.getFile(), _, _, loc.getEndLine(), loc.getEndColumn(), this, result)
|
||||
}
|
||||
|
||||
/** Gets the line on which the first token in this block starts. */
|
||||
int sourceStartLine() { tokens(this, 0, result, _, _, _) }
|
||||
/** Gets the line on which the first token in this block starts. */
|
||||
int sourceStartLine() { tokens(this, 0, result, _, _, _) }
|
||||
|
||||
/** Gets the column on which the first token in this block starts. */
|
||||
int sourceStartColumn() { tokens(this, 0, _, result, _, _) }
|
||||
/** Gets the column on which the first token in this block starts. */
|
||||
int sourceStartColumn() { tokens(this, 0, _, result, _, _) }
|
||||
|
||||
/** Gets the line on which the last token in this block ends. */
|
||||
int sourceEndLine() { tokens(this, this.lastToken(), _, _, result, _) }
|
||||
/** Gets the line on which the last token in this block ends. */
|
||||
int sourceEndLine() { tokens(this, this.lastToken(), _, _, result, _) }
|
||||
|
||||
/** Gets the column on which the last token in this block ends. */
|
||||
int sourceEndColumn() { tokens(this, this.lastToken(), _, _, _, result) }
|
||||
/** Gets the column on which the last token in this block ends. */
|
||||
int sourceEndColumn() { tokens(this, this.lastToken(), _, _, _, result) }
|
||||
|
||||
/** Gets the number of lines containing at least (part of) one token in this block. */
|
||||
int sourceLines() { result = this.sourceEndLine() + 1 - this.sourceStartLine() }
|
||||
/** Gets the number of lines containing at least (part of) one token in this block. */
|
||||
int sourceLines() { result = this.sourceEndLine() + 1 - this.sourceStartLine() }
|
||||
|
||||
/** Gets an opaque identifier for the equivalence class of this block. */
|
||||
int getEquivalenceClass() { duplicateCode(this, _, result) or similarCode(this, _, result) }
|
||||
/** Gets an opaque identifier for the equivalence class of this block. */
|
||||
int getEquivalenceClass() { duplicateCode(this, _, result) or similarCode(this, _, result) }
|
||||
|
||||
/** Gets the source file in which this block appears. */
|
||||
File sourceFile() {
|
||||
exists(string name | duplicateCode(this, name, _) or similarCode(this, name, _) |
|
||||
name.replaceAll("\\", "/") = relativePath(result)
|
||||
)
|
||||
}
|
||||
/** Gets the source file in which this block appears. */
|
||||
File sourceFile() {
|
||||
exists(string name | duplicateCode(this, name, _) or similarCode(this, name, _) |
|
||||
name.replaceAll("\\", "/") = relativePath(result)
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if this element is at the specified location.
|
||||
* The location spans column `startcolumn` of line `startline` to
|
||||
* column `endcolumn` of line `endline` in file `filepath`.
|
||||
* For more information, see
|
||||
* [Locations](https://help.semmle.com/QL/learn-ql/ql/locations.html).
|
||||
*/
|
||||
predicate hasLocationInfo(
|
||||
string filepath, int startline, int startcolumn, int endline, int endcolumn
|
||||
) {
|
||||
sourceFile().getAbsolutePath() = filepath and
|
||||
startline = sourceStartLine() and
|
||||
startcolumn = sourceStartColumn() and
|
||||
endline = sourceEndLine() and
|
||||
endcolumn = sourceEndColumn()
|
||||
}
|
||||
/**
|
||||
* Holds if this element is at the specified location.
|
||||
* The location spans column `startcolumn` of line `startline` to
|
||||
* column `endcolumn` of line `endline` in file `filepath`.
|
||||
* For more information, see
|
||||
* [Locations](https://help.semmle.com/QL/learn-ql/ql/locations.html).
|
||||
*/
|
||||
predicate hasLocationInfo(
|
||||
string filepath, int startline, int startcolumn, int endline, int endcolumn
|
||||
) {
|
||||
sourceFile().getAbsolutePath() = filepath and
|
||||
startline = sourceStartLine() and
|
||||
startcolumn = sourceStartColumn() and
|
||||
endline = sourceEndLine() and
|
||||
endcolumn = sourceEndColumn()
|
||||
}
|
||||
|
||||
/** Gets a textual representation of this element. */
|
||||
string toString() { result = "Copy" }
|
||||
/** Gets a textual representation of this element. */
|
||||
string toString() { result = "Copy" }
|
||||
|
||||
/**
|
||||
* Gets a block that extends this one, that is, its first token is also
|
||||
* covered by this block, but they are not the same block.
|
||||
*/
|
||||
Copy extendingBlock() {
|
||||
exists(File file, int sl, int sc, int ec, int el |
|
||||
tokenLocation(file, sl, sc, ec, el, this, _) and
|
||||
tokenLocation(file, sl, sc, ec, el, result, 0)
|
||||
) and
|
||||
this != result
|
||||
}
|
||||
/**
|
||||
* Gets a block that extends this one, that is, its first token is also
|
||||
* covered by this block, but they are not the same block.
|
||||
*/
|
||||
Copy extendingBlock() {
|
||||
exists(File file, int sl, int sc, int ec, int el |
|
||||
tokenLocation(file, sl, sc, ec, el, this, _) and
|
||||
tokenLocation(file, sl, sc, ec, el, result, 0)
|
||||
) and
|
||||
this != result
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -96,18 +96,18 @@ class Copy extends @duplication_or_similarity {
|
||||
* `start2`, and `end` the equivalence class of `end1` and `end2`.
|
||||
*/
|
||||
predicate similar_extension(
|
||||
SimilarBlock start1, SimilarBlock start2, SimilarBlock ext1, SimilarBlock ext2, int start, int ext
|
||||
SimilarBlock start1, SimilarBlock start2, SimilarBlock ext1, SimilarBlock ext2, int start, int ext
|
||||
) {
|
||||
start1.getEquivalenceClass() = start and
|
||||
start2.getEquivalenceClass() = start and
|
||||
ext1.getEquivalenceClass() = ext and
|
||||
ext2.getEquivalenceClass() = ext and
|
||||
start1 != start2 and
|
||||
(
|
||||
ext1 = start1 and ext2 = start2
|
||||
or
|
||||
similar_extension(start1.extendingBlock(), start2.extendingBlock(), ext1, ext2, _, ext)
|
||||
)
|
||||
start1.getEquivalenceClass() = start and
|
||||
start2.getEquivalenceClass() = start and
|
||||
ext1.getEquivalenceClass() = ext and
|
||||
ext2.getEquivalenceClass() = ext and
|
||||
start1 != start2 and
|
||||
(
|
||||
ext1 = start1 and ext2 = start2
|
||||
or
|
||||
similar_extension(start1.extendingBlock(), start2.extendingBlock(), ext1, ext2, _, ext)
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -117,31 +117,31 @@ predicate similar_extension(
|
||||
* `start2`, and `end` the equivalence class of `end1` and `end2`.
|
||||
*/
|
||||
predicate duplicate_extension(
|
||||
DuplicateBlock start1, DuplicateBlock start2, DuplicateBlock ext1, DuplicateBlock ext2, int start,
|
||||
int ext
|
||||
DuplicateBlock start1, DuplicateBlock start2, DuplicateBlock ext1, DuplicateBlock ext2, int start,
|
||||
int ext
|
||||
) {
|
||||
start1.getEquivalenceClass() = start and
|
||||
start2.getEquivalenceClass() = start and
|
||||
ext1.getEquivalenceClass() = ext and
|
||||
ext2.getEquivalenceClass() = ext and
|
||||
start1 != start2 and
|
||||
(
|
||||
ext1 = start1 and ext2 = start2
|
||||
or
|
||||
duplicate_extension(start1.extendingBlock(), start2.extendingBlock(), ext1, ext2, _, ext)
|
||||
)
|
||||
start1.getEquivalenceClass() = start and
|
||||
start2.getEquivalenceClass() = start and
|
||||
ext1.getEquivalenceClass() = ext and
|
||||
ext2.getEquivalenceClass() = ext and
|
||||
start1 != start2 and
|
||||
(
|
||||
ext1 = start1 and ext2 = start2
|
||||
or
|
||||
duplicate_extension(start1.extendingBlock(), start2.extendingBlock(), ext1, ext2, _, ext)
|
||||
)
|
||||
}
|
||||
|
||||
/** A block of duplicated code. */
|
||||
class DuplicateBlock extends Copy, @duplication {
|
||||
override string toString() { result = "Duplicate code: " + sourceLines() + " duplicated lines." }
|
||||
override string toString() { result = "Duplicate code: " + sourceLines() + " duplicated lines." }
|
||||
}
|
||||
|
||||
/** A block of similar code. */
|
||||
class SimilarBlock extends Copy, @similarity {
|
||||
override string toString() {
|
||||
result = "Similar code: " + sourceLines() + " almost duplicated lines."
|
||||
}
|
||||
override string toString() {
|
||||
result = "Similar code: " + sourceLines() + " almost duplicated lines."
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -149,14 +149,14 @@ class SimilarBlock extends Copy, @similarity {
|
||||
* respectively, where `scope1` and `scope2` are not the same.
|
||||
*/
|
||||
predicate duplicateStatement(Scope scope1, Scope scope2, Stmt stmt1, Stmt stmt2) {
|
||||
exists(int equivstart, int equivend, int first, int last |
|
||||
scope1.contains(stmt1) and
|
||||
scope2.contains(stmt2) and
|
||||
duplicateCoversStatement(equivstart, equivend, first, last, stmt1) and
|
||||
duplicateCoversStatement(equivstart, equivend, first, last, stmt2) and
|
||||
stmt1 != stmt2 and
|
||||
scope1 != scope2
|
||||
)
|
||||
exists(int equivstart, int equivend, int first, int last |
|
||||
scope1.contains(stmt1) and
|
||||
scope2.contains(stmt2) and
|
||||
duplicateCoversStatement(equivstart, equivend, first, last, stmt1) and
|
||||
duplicateCoversStatement(equivstart, equivend, first, last, stmt2) and
|
||||
stmt1 != stmt2 and
|
||||
scope1 != scope2
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -167,17 +167,17 @@ predicate duplicateStatement(Scope scope1, Scope scope2, Stmt stmt1, Stmt stmt2)
|
||||
* block, respectively.
|
||||
*/
|
||||
private predicate duplicateCoversStatement(
|
||||
int equivstart, int equivend, int first, int last, Stmt stmt
|
||||
int equivstart, int equivend, int first, int last, Stmt stmt
|
||||
) {
|
||||
exists(DuplicateBlock b1, DuplicateBlock b2, Location startloc, Location endloc |
|
||||
stmt.getLocation() = startloc and
|
||||
stmt.getLastStatement().getLocation() = endloc and
|
||||
first = b1.tokenStartingAt(startloc) and
|
||||
last = b2.tokenEndingAt(endloc) and
|
||||
b1.getEquivalenceClass() = equivstart and
|
||||
b2.getEquivalenceClass() = equivend and
|
||||
duplicate_extension(b1, _, b2, _, equivstart, equivend)
|
||||
)
|
||||
exists(DuplicateBlock b1, DuplicateBlock b2, Location startloc, Location endloc |
|
||||
stmt.getLocation() = startloc and
|
||||
stmt.getLastStatement().getLocation() = endloc and
|
||||
first = b1.tokenStartingAt(startloc) and
|
||||
last = b2.tokenEndingAt(endloc) and
|
||||
b1.getEquivalenceClass() = equivstart and
|
||||
b2.getEquivalenceClass() = equivend and
|
||||
duplicate_extension(b1, _, b2, _, equivstart, equivend)
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -185,23 +185,23 @@ private predicate duplicateCoversStatement(
|
||||
* toplevel that has `duplicate` lines in common with `scope1`.
|
||||
*/
|
||||
predicate duplicateStatements(Scope scope1, Scope scope2, int duplicate, int total) {
|
||||
duplicate = strictcount(Stmt stmt | duplicateStatement(scope1, scope2, stmt, _)) and
|
||||
total = strictcount(Stmt stmt | scope1.contains(stmt))
|
||||
duplicate = strictcount(Stmt stmt | duplicateStatement(scope1, scope2, stmt, _)) and
|
||||
total = strictcount(Stmt stmt | scope1.contains(stmt))
|
||||
}
|
||||
|
||||
/**
|
||||
* Find pairs of scopes that are identical or almost identical
|
||||
*/
|
||||
predicate duplicateScopes(Scope s, Scope other, float percent, string message) {
|
||||
exists(int total, int duplicate | duplicateStatements(s, other, duplicate, total) |
|
||||
percent = 100.0 * duplicate / total and
|
||||
percent >= 80.0 and
|
||||
if duplicate = total
|
||||
then message = "All " + total + " statements in " + s.getName() + " are identical in $@."
|
||||
else
|
||||
message =
|
||||
duplicate + " out of " + total + " statements in " + s.getName() + " are duplicated in $@."
|
||||
)
|
||||
exists(int total, int duplicate | duplicateStatements(s, other, duplicate, total) |
|
||||
percent = 100.0 * duplicate / total and
|
||||
percent >= 80.0 and
|
||||
if duplicate = total
|
||||
then message = "All " + total + " statements in " + s.getName() + " are identical in $@."
|
||||
else
|
||||
message =
|
||||
duplicate + " out of " + total + " statements in " + s.getName() + " are duplicated in $@."
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -209,14 +209,14 @@ predicate duplicateScopes(Scope s, Scope other, float percent, string message) {
|
||||
* respectively, where `scope1` and `scope2` are not the same.
|
||||
*/
|
||||
private predicate similarStatement(Scope scope1, Scope scope2, Stmt stmt1, Stmt stmt2) {
|
||||
exists(int start, int end, int first, int last |
|
||||
scope1.contains(stmt1) and
|
||||
scope2.contains(stmt2) and
|
||||
similarCoversStatement(start, end, first, last, stmt1) and
|
||||
similarCoversStatement(start, end, first, last, stmt2) and
|
||||
stmt1 != stmt2 and
|
||||
scope1 != scope2
|
||||
)
|
||||
exists(int start, int end, int first, int last |
|
||||
scope1.contains(stmt1) and
|
||||
scope2.contains(stmt2) and
|
||||
similarCoversStatement(start, end, first, last, stmt1) and
|
||||
similarCoversStatement(start, end, first, last, stmt2) and
|
||||
stmt1 != stmt2 and
|
||||
scope1 != scope2
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -227,17 +227,17 @@ private predicate similarStatement(Scope scope1, Scope scope2, Stmt stmt1, Stmt
|
||||
* block, respectively.
|
||||
*/
|
||||
private predicate similarCoversStatement(
|
||||
int equivstart, int equivend, int first, int last, Stmt stmt
|
||||
int equivstart, int equivend, int first, int last, Stmt stmt
|
||||
) {
|
||||
exists(SimilarBlock b1, SimilarBlock b2, Location startloc, Location endloc |
|
||||
stmt.getLocation() = startloc and
|
||||
stmt.getLastStatement().getLocation() = endloc and
|
||||
first = b1.tokenStartingAt(startloc) and
|
||||
last = b2.tokenEndingAt(endloc) and
|
||||
b1.getEquivalenceClass() = equivstart and
|
||||
b2.getEquivalenceClass() = equivend and
|
||||
similar_extension(b1, _, b2, _, equivstart, equivend)
|
||||
)
|
||||
exists(SimilarBlock b1, SimilarBlock b2, Location startloc, Location endloc |
|
||||
stmt.getLocation() = startloc and
|
||||
stmt.getLastStatement().getLocation() = endloc and
|
||||
first = b1.tokenStartingAt(startloc) and
|
||||
last = b2.tokenEndingAt(endloc) and
|
||||
b1.getEquivalenceClass() = equivstart and
|
||||
b2.getEquivalenceClass() = equivend and
|
||||
similar_extension(b1, _, b2, _, equivstart, equivend)
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -245,23 +245,23 @@ private predicate similarCoversStatement(
|
||||
* toplevel that has `similar` similar lines to `scope1`.
|
||||
*/
|
||||
private predicate similarStatements(Scope scope1, Scope scope2, int similar, int total) {
|
||||
similar = strictcount(Stmt stmt | similarStatement(scope1, scope2, stmt, _)) and
|
||||
total = strictcount(Stmt stmt | scope1.contains(stmt))
|
||||
similar = strictcount(Stmt stmt | similarStatement(scope1, scope2, stmt, _)) and
|
||||
total = strictcount(Stmt stmt | scope1.contains(stmt))
|
||||
}
|
||||
|
||||
/**
|
||||
* Find pairs of scopes that are similar
|
||||
*/
|
||||
predicate similarScopes(Scope s, Scope other, float percent, string message) {
|
||||
exists(int total, int similar | similarStatements(s, other, similar, total) |
|
||||
percent = 100.0 * similar / total and
|
||||
percent >= 80.0 and
|
||||
if similar = total
|
||||
then message = "All statements in " + s.getName() + " are similar in $@."
|
||||
else
|
||||
message =
|
||||
similar + " out of " + total + " statements in " + s.getName() + " are similar in $@."
|
||||
)
|
||||
exists(int total, int similar | similarStatements(s, other, similar, total) |
|
||||
percent = 100.0 * similar / total and
|
||||
percent >= 80.0 and
|
||||
if similar = total
|
||||
then message = "All statements in " + s.getName() + " are similar in $@."
|
||||
else
|
||||
message =
|
||||
similar + " out of " + total + " statements in " + s.getName() + " are similar in $@."
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -269,5 +269,5 @@ predicate similarScopes(Scope s, Scope other, float percent, string message) {
|
||||
* This is true for blocks of import statements.
|
||||
*/
|
||||
predicate allowlistedLineForDuplication(File f, int line) {
|
||||
exists(ImportingStmt i | i.getLocation().getFile() = f and i.getLocation().getStartLine() = line)
|
||||
exists(ImportingStmt i | i.getLocation().getFile() = f and i.getLocation().getStartLine() = line)
|
||||
}
|
||||
|
||||
94
python/ql/src/external/DefectFilter.qll
vendored
94
python/ql/src/external/DefectFilter.qll
vendored
@@ -11,71 +11,71 @@ import semmle.python.Files
|
||||
* For more information, see [Locations](https://help.semmle.com/QL/learn-ql/ql/locations.html).
|
||||
*/
|
||||
external predicate defectResults(
|
||||
int id, string queryPath, string filepath, int startline, int startcol, int endline, int endcol,
|
||||
string message
|
||||
int id, string queryPath, string filepath, int startline, int startcol, int endline, int endcol,
|
||||
string message
|
||||
);
|
||||
|
||||
/**
|
||||
* A defect query result stored in a dashboard database.
|
||||
*/
|
||||
class DefectResult extends int {
|
||||
DefectResult() { defectResults(this, _, _, _, _, _, _, _) }
|
||||
DefectResult() { defectResults(this, _, _, _, _, _, _, _) }
|
||||
|
||||
/** Gets the path of the query that reported the result. */
|
||||
string getQueryPath() { defectResults(this, result, _, _, _, _, _, _) }
|
||||
/** Gets the path of the query that reported the result. */
|
||||
string getQueryPath() { defectResults(this, result, _, _, _, _, _, _) }
|
||||
|
||||
/** Gets the file in which this query result was reported. */
|
||||
File getFile() {
|
||||
exists(string path |
|
||||
defectResults(this, _, path, _, _, _, _, _) and result.getAbsolutePath() = path
|
||||
)
|
||||
}
|
||||
/** Gets the file in which this query result was reported. */
|
||||
File getFile() {
|
||||
exists(string path |
|
||||
defectResults(this, _, path, _, _, _, _, _) and result.getAbsolutePath() = path
|
||||
)
|
||||
}
|
||||
|
||||
/** Gets the file path in which this query result was reported. */
|
||||
string getFilePath() { defectResults(this, _, result, _, _, _, _, _) }
|
||||
/** Gets the file path in which this query result was reported. */
|
||||
string getFilePath() { defectResults(this, _, result, _, _, _, _, _) }
|
||||
|
||||
/** Gets the line on which the location of this query result starts. */
|
||||
int getStartLine() { defectResults(this, _, _, result, _, _, _, _) }
|
||||
/** Gets the line on which the location of this query result starts. */
|
||||
int getStartLine() { defectResults(this, _, _, result, _, _, _, _) }
|
||||
|
||||
/** Gets the column on which the location of this query result starts. */
|
||||
int getStartColumn() { defectResults(this, _, _, _, result, _, _, _) }
|
||||
/** Gets the column on which the location of this query result starts. */
|
||||
int getStartColumn() { defectResults(this, _, _, _, result, _, _, _) }
|
||||
|
||||
/** Gets the line on which the location of this query result ends. */
|
||||
int getEndLine() { defectResults(this, _, _, _, _, result, _, _) }
|
||||
/** Gets the line on which the location of this query result ends. */
|
||||
int getEndLine() { defectResults(this, _, _, _, _, result, _, _) }
|
||||
|
||||
/** Gets the column on which the location of this query result ends. */
|
||||
int getEndColumn() { defectResults(this, _, _, _, _, _, result, _) }
|
||||
/** Gets the column on which the location of this query result ends. */
|
||||
int getEndColumn() { defectResults(this, _, _, _, _, _, result, _) }
|
||||
|
||||
/** Gets the message associated with this query result. */
|
||||
string getMessage() { defectResults(this, _, _, _, _, _, _, result) }
|
||||
/** Gets the message associated with this query result. */
|
||||
string getMessage() { defectResults(this, _, _, _, _, _, _, result) }
|
||||
|
||||
/**
|
||||
* Holds if this element is at the specified location.
|
||||
* The location spans column `startcolumn` of line `startline` to
|
||||
* column `endcolumn` of line `endline` in file `filepath`.
|
||||
* For more information, see
|
||||
* [Locations](https://help.semmle.com/QL/learn-ql/ql/locations.html).
|
||||
*/
|
||||
predicate hasLocationInfo(
|
||||
string filepath, int startline, int startcolumn, int endline, int endcolumn
|
||||
) {
|
||||
defectResults(this, _, filepath, startline, startcolumn, endline, endcolumn, _)
|
||||
}
|
||||
/**
|
||||
* Holds if this element is at the specified location.
|
||||
* The location spans column `startcolumn` of line `startline` to
|
||||
* column `endcolumn` of line `endline` in file `filepath`.
|
||||
* For more information, see
|
||||
* [Locations](https://help.semmle.com/QL/learn-ql/ql/locations.html).
|
||||
*/
|
||||
predicate hasLocationInfo(
|
||||
string filepath, int startline, int startcolumn, int endline, int endcolumn
|
||||
) {
|
||||
defectResults(this, _, filepath, startline, startcolumn, endline, endcolumn, _)
|
||||
}
|
||||
|
||||
/** Gets the URL corresponding to the location of this query result. */
|
||||
string getURL() {
|
||||
result =
|
||||
"file://" + getFile().getAbsolutePath() + ":" + getStartLine() + ":" + getStartColumn() + ":" +
|
||||
getEndLine() + ":" + getEndColumn()
|
||||
}
|
||||
/** Gets the URL corresponding to the location of this query result. */
|
||||
string getURL() {
|
||||
result =
|
||||
"file://" + getFile().getAbsolutePath() + ":" + getStartLine() + ":" + getStartColumn() + ":" +
|
||||
getEndLine() + ":" + getEndColumn()
|
||||
}
|
||||
}
|
||||
|
||||
// crude containment by line number only
|
||||
predicate contains(Location l, DefectResult res) {
|
||||
exists(string path, int bl1, int el1, int bl2, int el2 |
|
||||
l.hasLocationInfo(path, bl1, _, el1, _) and
|
||||
res.hasLocationInfo(path, bl2, _, el2, _) and
|
||||
bl1 <= bl2 and
|
||||
el1 >= el2
|
||||
)
|
||||
exists(string path, int bl1, int el1, int bl2, int el2 |
|
||||
l.hasLocationInfo(path, bl1, _, el1, _) and
|
||||
res.hasLocationInfo(path, bl2, _, el2, _) and
|
||||
bl1 <= bl2 and
|
||||
el1 >= el2
|
||||
)
|
||||
}
|
||||
|
||||
16
python/ql/src/external/DuplicateBlock.ql
vendored
16
python/ql/src/external/DuplicateBlock.ql
vendored
@@ -19,16 +19,16 @@ import python
|
||||
import CodeDuplication
|
||||
|
||||
predicate sorted_by_location(DuplicateBlock x, DuplicateBlock y) {
|
||||
if x.sourceFile() = y.sourceFile()
|
||||
then x.sourceStartLine() < y.sourceStartLine()
|
||||
else x.sourceFile().getAbsolutePath() < y.sourceFile().getAbsolutePath()
|
||||
if x.sourceFile() = y.sourceFile()
|
||||
then x.sourceStartLine() < y.sourceStartLine()
|
||||
else x.sourceFile().getAbsolutePath() < y.sourceFile().getAbsolutePath()
|
||||
}
|
||||
|
||||
from DuplicateBlock d, DuplicateBlock other
|
||||
where
|
||||
d.sourceLines() > 10 and
|
||||
other.getEquivalenceClass() = d.getEquivalenceClass() and
|
||||
sorted_by_location(other, d)
|
||||
d.sourceLines() > 10 and
|
||||
other.getEquivalenceClass() = d.getEquivalenceClass() and
|
||||
sorted_by_location(other, d)
|
||||
select d,
|
||||
"Duplicate code: " + d.sourceLines() + " lines are duplicated at " +
|
||||
other.sourceFile().getShortName() + ":" + other.sourceStartLine().toString()
|
||||
"Duplicate code: " + d.sourceLines() + " lines are duplicated at " +
|
||||
other.sourceFile().getShortName() + ":" + other.sourceStartLine().toString()
|
||||
|
||||
10
python/ql/src/external/DuplicateFunction.ql
vendored
10
python/ql/src/external/DuplicateFunction.ql
vendored
@@ -21,9 +21,9 @@ predicate relevant(Function m) { m.getMetrics().getNumberOfLinesOfCode() > 5 }
|
||||
|
||||
from Function m, Function other, string message, int percent
|
||||
where
|
||||
duplicateScopes(m, other, percent, message) and
|
||||
relevant(m) and
|
||||
percent > 95.0 and
|
||||
not duplicateScopes(m.getEnclosingModule(), other.getEnclosingModule(), _, _) and
|
||||
not duplicateScopes(m.getScope(), other.getScope(), _, _)
|
||||
duplicateScopes(m, other, percent, message) and
|
||||
relevant(m) and
|
||||
percent > 95.0 and
|
||||
not duplicateScopes(m.getEnclosingModule(), other.getEnclosingModule(), _, _) and
|
||||
not duplicateScopes(m.getScope(), other.getScope(), _, _)
|
||||
select m, message, other, other.getName()
|
||||
|
||||
94
python/ql/src/external/ExternalArtifact.qll
vendored
94
python/ql/src/external/ExternalArtifact.qll
vendored
@@ -5,83 +5,83 @@
|
||||
import python
|
||||
|
||||
class ExternalDefect extends @externalDefect {
|
||||
string getQueryPath() {
|
||||
exists(string path |
|
||||
externalDefects(this, path, _, _, _) and
|
||||
result = path.replaceAll("\\", "/")
|
||||
)
|
||||
}
|
||||
string getQueryPath() {
|
||||
exists(string path |
|
||||
externalDefects(this, path, _, _, _) and
|
||||
result = path.replaceAll("\\", "/")
|
||||
)
|
||||
}
|
||||
|
||||
string getMessage() { externalDefects(this, _, _, result, _) }
|
||||
string getMessage() { externalDefects(this, _, _, result, _) }
|
||||
|
||||
float getSeverity() { externalDefects(this, _, _, _, result) }
|
||||
float getSeverity() { externalDefects(this, _, _, _, result) }
|
||||
|
||||
Location getLocation() { externalDefects(this, _, result, _, _) }
|
||||
Location getLocation() { externalDefects(this, _, result, _, _) }
|
||||
|
||||
/** Gets a textual representation of this element. */
|
||||
string toString() { result = getQueryPath() + ": " + getLocation() + " - " + getMessage() }
|
||||
/** Gets a textual representation of this element. */
|
||||
string toString() { result = getQueryPath() + ": " + getLocation() + " - " + getMessage() }
|
||||
}
|
||||
|
||||
class ExternalMetric extends @externalMetric {
|
||||
string getQueryPath() { externalMetrics(this, result, _, _) }
|
||||
string getQueryPath() { externalMetrics(this, result, _, _) }
|
||||
|
||||
float getValue() { externalMetrics(this, _, _, result) }
|
||||
float getValue() { externalMetrics(this, _, _, result) }
|
||||
|
||||
Location getLocation() { externalMetrics(this, _, result, _) }
|
||||
Location getLocation() { externalMetrics(this, _, result, _) }
|
||||
|
||||
/** Gets a textual representation of this element. */
|
||||
string toString() { result = getQueryPath() + ": " + getLocation() + " - " + getValue() }
|
||||
/** Gets a textual representation of this element. */
|
||||
string toString() { result = getQueryPath() + ": " + getLocation() + " - " + getValue() }
|
||||
}
|
||||
|
||||
/**
|
||||
* An external data item.
|
||||
*/
|
||||
class ExternalData extends @externalDataElement {
|
||||
/** Gets the path of the file this data was loaded from. */
|
||||
string getDataPath() { externalData(this, result, _, _) }
|
||||
/** Gets the path of the file this data was loaded from. */
|
||||
string getDataPath() { externalData(this, result, _, _) }
|
||||
|
||||
/**
|
||||
* Gets the path of the file this data was loaded from, with its
|
||||
* extension replaced by `.ql`.
|
||||
*/
|
||||
string getQueryPath() { result = getDataPath().regexpReplaceAll("\\.[^.]*$", ".ql") }
|
||||
/**
|
||||
* Gets the path of the file this data was loaded from, with its
|
||||
* extension replaced by `.ql`.
|
||||
*/
|
||||
string getQueryPath() { result = getDataPath().regexpReplaceAll("\\.[^.]*$", ".ql") }
|
||||
|
||||
/** Gets the number of fields in this data item. */
|
||||
int getNumFields() { result = 1 + max(int i | externalData(this, _, i, _) | i) }
|
||||
/** Gets the number of fields in this data item. */
|
||||
int getNumFields() { result = 1 + max(int i | externalData(this, _, i, _) | i) }
|
||||
|
||||
/** Gets the value of the field at position `index` of this data item. */
|
||||
string getField(int index) { externalData(this, _, index, result) }
|
||||
/** Gets the value of the field at position `index` of this data item. */
|
||||
string getField(int index) { externalData(this, _, index, result) }
|
||||
|
||||
/** Gets the integer value of the field at position `index` of this data item. */
|
||||
int getFieldAsInt(int index) { result = getField(index).toInt() }
|
||||
/** Gets the integer value of the field at position `index` of this data item. */
|
||||
int getFieldAsInt(int index) { result = getField(index).toInt() }
|
||||
|
||||
/** Gets the floating-point value of the field at position `index` of this data item. */
|
||||
float getFieldAsFloat(int index) { result = getField(index).toFloat() }
|
||||
/** Gets the floating-point value of the field at position `index` of this data item. */
|
||||
float getFieldAsFloat(int index) { result = getField(index).toFloat() }
|
||||
|
||||
/** Gets the value of the field at position `index` of this data item, interpreted as a date. */
|
||||
date getFieldAsDate(int index) { result = getField(index).toDate() }
|
||||
/** Gets the value of the field at position `index` of this data item, interpreted as a date. */
|
||||
date getFieldAsDate(int index) { result = getField(index).toDate() }
|
||||
|
||||
/** Gets a textual representation of this data item. */
|
||||
string toString() { result = getQueryPath() + ": " + buildTupleString(0) }
|
||||
/** Gets a textual representation of this data item. */
|
||||
string toString() { result = getQueryPath() + ": " + buildTupleString(0) }
|
||||
|
||||
/** Gets a textual representation of this data item, starting with the field at position `start`. */
|
||||
private string buildTupleString(int start) {
|
||||
start = getNumFields() - 1 and result = getField(start)
|
||||
or
|
||||
start < getNumFields() - 1 and result = getField(start) + "," + buildTupleString(start + 1)
|
||||
}
|
||||
/** Gets a textual representation of this data item, starting with the field at position `start`. */
|
||||
private string buildTupleString(int start) {
|
||||
start = getNumFields() - 1 and result = getField(start)
|
||||
or
|
||||
start < getNumFields() - 1 and result = getField(start) + "," + buildTupleString(start + 1)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* External data with a location, and a message, as produced by tools that used to produce QLDs.
|
||||
*/
|
||||
class DefectExternalData extends ExternalData {
|
||||
DefectExternalData() {
|
||||
this.getField(0).regexpMatch("\\w+://.*:[0-9]+:[0-9]+:[0-9]+:[0-9]+$") and
|
||||
this.getNumFields() = 2
|
||||
}
|
||||
DefectExternalData() {
|
||||
this.getField(0).regexpMatch("\\w+://.*:[0-9]+:[0-9]+:[0-9]+:[0-9]+$") and
|
||||
this.getNumFields() = 2
|
||||
}
|
||||
|
||||
string getURL() { result = getField(0) }
|
||||
string getURL() { result = getField(0) }
|
||||
|
||||
string getMessage() { result = getField(1) }
|
||||
string getMessage() { result = getField(1) }
|
||||
}
|
||||
|
||||
@@ -19,7 +19,7 @@ import CodeDuplication
|
||||
|
||||
from Class c, Class other, string message
|
||||
where
|
||||
duplicateScopes(c, other, _, message) and
|
||||
count(c.getAStmt()) > 3 and
|
||||
not duplicateScopes(c.getEnclosingModule(), _, _, _)
|
||||
duplicateScopes(c, other, _, message) and
|
||||
count(c.getAStmt()) > 3 and
|
||||
not duplicateScopes(c.getEnclosingModule(), _, _, _)
|
||||
select c, message, other, other.getName()
|
||||
|
||||
12
python/ql/src/external/SimilarFunction.ql
vendored
12
python/ql/src/external/SimilarFunction.ql
vendored
@@ -21,10 +21,10 @@ predicate relevant(Function m) { m.getMetrics().getNumberOfLinesOfCode() > 10 }
|
||||
|
||||
from Function m, Function other, string message, int percent
|
||||
where
|
||||
similarScopes(m, other, percent, message) and
|
||||
relevant(m) and
|
||||
percent > 95.0 and
|
||||
not duplicateScopes(m, other, _, _) and
|
||||
not duplicateScopes(m.getEnclosingModule(), other.getEnclosingModule(), _, _) and
|
||||
not duplicateScopes(m.getScope(), other.getScope(), _, _)
|
||||
similarScopes(m, other, percent, message) and
|
||||
relevant(m) and
|
||||
percent > 95.0 and
|
||||
not duplicateScopes(m, other, _, _) and
|
||||
not duplicateScopes(m.getEnclosingModule(), other.getEnclosingModule(), _, _) and
|
||||
not duplicateScopes(m.getScope(), other.getScope(), _, _)
|
||||
select m, message, other, other.getName()
|
||||
|
||||
216
python/ql/src/external/Thrift.qll
vendored
216
python/ql/src/external/Thrift.qll
vendored
@@ -7,197 +7,201 @@ import external.ExternalArtifact
|
||||
|
||||
/** An item in the parse tree of the IDL file */
|
||||
class ThriftElement extends ExternalData {
|
||||
string kind;
|
||||
string kind;
|
||||
|
||||
ThriftElement() { this.getDataPath() = "thrift-" + kind }
|
||||
ThriftElement() { this.getDataPath() = "thrift-" + kind }
|
||||
|
||||
string getKind() { result = kind }
|
||||
string getKind() { result = kind }
|
||||
|
||||
string getId() { result = getField(0) }
|
||||
string getId() { result = getField(0) }
|
||||
|
||||
int getIndex() { result = getFieldAsInt(1) }
|
||||
int getIndex() { result = getFieldAsInt(1) }
|
||||
|
||||
ThriftElement getParent() { result.getId() = this.getField(2) }
|
||||
ThriftElement getParent() { result.getId() = this.getField(2) }
|
||||
|
||||
string getValue() { result = this.getField(3) }
|
||||
string getValue() { result = this.getField(3) }
|
||||
|
||||
ThriftElement getChild(int n) { result.getIndex() = n and result.getParent() = this }
|
||||
ThriftElement getChild(int n) { result.getIndex() = n and result.getParent() = this }
|
||||
|
||||
ThriftElement getAChild() { result = this.getChild(_) }
|
||||
ThriftElement getAChild() { result = this.getChild(_) }
|
||||
|
||||
override string toString() { result = this.getKind() }
|
||||
override string toString() { result = this.getKind() }
|
||||
|
||||
string getPath() { result = this.getField(4) }
|
||||
string getPath() { result = this.getField(4) }
|
||||
|
||||
private int line() { result = this.getFieldAsInt(5) }
|
||||
private int line() { result = this.getFieldAsInt(5) }
|
||||
|
||||
private int column() { result = this.getFieldAsInt(6) }
|
||||
private int column() { result = this.getFieldAsInt(6) }
|
||||
|
||||
/**
|
||||
* Holds if this element is at the specified location.
|
||||
* The location spans column `startcolumn` of line `startline` to
|
||||
* column `endcolumn` of line `endline` in file `filepath`.
|
||||
* For more information, see
|
||||
* [Locations](https://help.semmle.com/QL/learn-ql/ql/locations.html).
|
||||
*/
|
||||
predicate hasLocationInfo(
|
||||
string filepath, int startline, int startcolumn, int endline, int endcolumn
|
||||
) {
|
||||
filepath = this.getPath() and
|
||||
startline = this.line() and
|
||||
startcolumn = this.column() and
|
||||
endline = this.line() and
|
||||
endcolumn = this.column() + this.getValue().length() - 1
|
||||
or
|
||||
exists(ThriftElement first, ThriftElement last |
|
||||
first = this.getChild(min(int l | exists(this.getChild(l)))) and
|
||||
last = this.getChild(max(int l | exists(this.getChild(l)))) and
|
||||
first.hasLocationInfo(filepath, startline, startcolumn, _, _) and
|
||||
last.hasLocationInfo(filepath, _, _, endline, endcolumn)
|
||||
)
|
||||
}
|
||||
/**
|
||||
* Holds if this element is at the specified location.
|
||||
* The location spans column `startcolumn` of line `startline` to
|
||||
* column `endcolumn` of line `endline` in file `filepath`.
|
||||
* For more information, see
|
||||
* [Locations](https://help.semmle.com/QL/learn-ql/ql/locations.html).
|
||||
*/
|
||||
predicate hasLocationInfo(
|
||||
string filepath, int startline, int startcolumn, int endline, int endcolumn
|
||||
) {
|
||||
filepath = this.getPath() and
|
||||
startline = this.line() and
|
||||
startcolumn = this.column() and
|
||||
endline = this.line() and
|
||||
endcolumn = this.column() + this.getValue().length() - 1
|
||||
or
|
||||
exists(ThriftElement first, ThriftElement last |
|
||||
first = this.getChild(min(int l | exists(this.getChild(l)))) and
|
||||
last = this.getChild(max(int l | exists(this.getChild(l)))) and
|
||||
first.hasLocationInfo(filepath, startline, startcolumn, _, _) and
|
||||
last.hasLocationInfo(filepath, _, _, endline, endcolumn)
|
||||
)
|
||||
}
|
||||
|
||||
File getFile() { this.hasLocationInfo(result.getAbsolutePath(), _, _, _, _) }
|
||||
File getFile() { this.hasLocationInfo(result.getAbsolutePath(), _, _, _, _) }
|
||||
}
|
||||
|
||||
abstract class ThriftNamedElement extends ThriftElement {
|
||||
abstract ThriftElement getNameElement();
|
||||
abstract ThriftElement getNameElement();
|
||||
|
||||
final string getName() { result = this.getNameElement().getValue() }
|
||||
final string getName() { result = this.getNameElement().getValue() }
|
||||
|
||||
override string toString() {
|
||||
result = this.getKind() + " " + this.getName()
|
||||
or
|
||||
not exists(this.getName()) and result = this.getKind() + " ???"
|
||||
}
|
||||
override string toString() {
|
||||
result = this.getKind() + " " + this.getName()
|
||||
or
|
||||
not exists(this.getName()) and result = this.getKind() + " ???"
|
||||
}
|
||||
|
||||
override predicate hasLocationInfo(string filepath, int startline, int startcolumn, int endline, int endcolumn) {
|
||||
exists(ThriftElement first |
|
||||
first = this.getChild(min(int l | exists(this.getChild(l)))) and
|
||||
first.hasLocationInfo(filepath, startline, startcolumn, _, _) and
|
||||
this.getNameElement().hasLocationInfo(filepath, _, _, endline, endcolumn)
|
||||
)
|
||||
}
|
||||
override predicate hasLocationInfo(
|
||||
string filepath, int startline, int startcolumn, int endline, int endcolumn
|
||||
) {
|
||||
exists(ThriftElement first |
|
||||
first = this.getChild(min(int l | exists(this.getChild(l)))) and
|
||||
first.hasLocationInfo(filepath, startline, startcolumn, _, _) and
|
||||
this.getNameElement().hasLocationInfo(filepath, _, _, endline, endcolumn)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
class ThriftType extends ThriftNamedElement {
|
||||
ThriftType() { kind.matches("%type") }
|
||||
ThriftType() { kind.matches("%type") }
|
||||
|
||||
override ThriftElement getNameElement() {
|
||||
result = this.getChild(0)
|
||||
or
|
||||
result = this.getChild(0).(ThriftType).getNameElement()
|
||||
}
|
||||
override ThriftElement getNameElement() {
|
||||
result = this.getChild(0)
|
||||
or
|
||||
result = this.getChild(0).(ThriftType).getNameElement()
|
||||
}
|
||||
|
||||
override string toString() { result = "type " + this.getName() }
|
||||
override string toString() { result = "type " + this.getName() }
|
||||
|
||||
predicate references(ThriftStruct struct) {
|
||||
this.getName() = struct.getName() and
|
||||
exists(string path |
|
||||
this.hasLocationInfo(path, _, _, _, _) and
|
||||
struct.hasLocationInfo(path, _, _, _, _)
|
||||
)
|
||||
}
|
||||
predicate references(ThriftStruct struct) {
|
||||
this.getName() = struct.getName() and
|
||||
exists(string path |
|
||||
this.hasLocationInfo(path, _, _, _, _) and
|
||||
struct.hasLocationInfo(path, _, _, _, _)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/** A thrift typedef */
|
||||
class ThriftTypeDef extends ThriftNamedElement {
|
||||
ThriftTypeDef() { kind.matches("typedef") }
|
||||
ThriftTypeDef() { kind.matches("typedef") }
|
||||
|
||||
override ThriftElement getNameElement() { result = this.getChild(2).getChild(0) }
|
||||
override ThriftElement getNameElement() { result = this.getChild(2).getChild(0) }
|
||||
}
|
||||
|
||||
/** A thrift enum declaration */
|
||||
class ThriftEnum extends ThriftNamedElement {
|
||||
ThriftEnum() { kind.matches("enum") }
|
||||
ThriftEnum() { kind.matches("enum") }
|
||||
|
||||
override ThriftElement getNameElement() { result = this.getChild(0).getChild(0) }
|
||||
override ThriftElement getNameElement() { result = this.getChild(0).getChild(0) }
|
||||
}
|
||||
|
||||
/** A thrift enum field */
|
||||
class ThriftEnumField extends ThriftNamedElement {
|
||||
ThriftEnumField() { kind.matches("enumfield") }
|
||||
ThriftEnumField() { kind.matches("enumfield") }
|
||||
|
||||
override ThriftElement getNameElement() { result = this.getChild(0).getChild(0) }
|
||||
override ThriftElement getNameElement() { result = this.getChild(0).getChild(0) }
|
||||
}
|
||||
|
||||
/** A thrift service declaration */
|
||||
class ThriftService extends ThriftNamedElement {
|
||||
ThriftService() { kind.matches("service") }
|
||||
ThriftService() { kind.matches("service") }
|
||||
|
||||
override ThriftElement getNameElement() { result = this.getChild(0).getChild(0) }
|
||||
override ThriftElement getNameElement() { result = this.getChild(0).getChild(0) }
|
||||
|
||||
ThriftFunction getAFunction() { result = this.getChild(_) }
|
||||
ThriftFunction getAFunction() { result = this.getChild(_) }
|
||||
|
||||
ThriftFunction getFunction(string name) {
|
||||
result.getName() = name and
|
||||
result = this.getAFunction()
|
||||
}
|
||||
ThriftFunction getFunction(string name) {
|
||||
result.getName() = name and
|
||||
result = this.getAFunction()
|
||||
}
|
||||
}
|
||||
|
||||
/** A thrift function declaration */
|
||||
class ThriftFunction extends ThriftNamedElement {
|
||||
ThriftFunction() { kind.matches("function") }
|
||||
ThriftFunction() { kind.matches("function") }
|
||||
|
||||
override ThriftElement getNameElement() { result = this.getChild(2).getChild(0) }
|
||||
override ThriftElement getNameElement() { result = this.getChild(2).getChild(0) }
|
||||
|
||||
ThriftField getArgument(int n) { result = this.getChild(n + 3) }
|
||||
ThriftField getArgument(int n) { result = this.getChild(n + 3) }
|
||||
|
||||
ThriftField getAnArgument() { result = this.getArgument(_) }
|
||||
ThriftField getAnArgument() { result = this.getArgument(_) }
|
||||
|
||||
private ThriftThrows getAllThrows() { result = this.getChild(_) }
|
||||
private ThriftThrows getAllThrows() { result = this.getChild(_) }
|
||||
|
||||
ThriftField getAThrows() { result = this.getAllThrows().getAChild() }
|
||||
ThriftField getAThrows() { result = this.getAllThrows().getAChild() }
|
||||
|
||||
ThriftType getReturnType() { result = this.getChild(1).getChild(0) }
|
||||
ThriftType getReturnType() { result = this.getChild(1).getChild(0) }
|
||||
|
||||
override predicate hasLocationInfo(string filepath, int startline, int startcolumn, int endline, int endcolumn) {
|
||||
this.getChild(1).hasLocationInfo(filepath, startline, startcolumn, _, _) and
|
||||
this.getChild(2).hasLocationInfo(filepath, _, _, endline, endcolumn)
|
||||
}
|
||||
override predicate hasLocationInfo(
|
||||
string filepath, int startline, int startcolumn, int endline, int endcolumn
|
||||
) {
|
||||
this.getChild(1).hasLocationInfo(filepath, startline, startcolumn, _, _) and
|
||||
this.getChild(2).hasLocationInfo(filepath, _, _, endline, endcolumn)
|
||||
}
|
||||
|
||||
ThriftService getService() { result.getAFunction() = this }
|
||||
ThriftService getService() { result.getAFunction() = this }
|
||||
|
||||
string getQualifiedName() { result = this.getService().getName() + "." + this.getName() }
|
||||
string getQualifiedName() { result = this.getService().getName() + "." + this.getName() }
|
||||
}
|
||||
|
||||
class ThriftField extends ThriftNamedElement {
|
||||
ThriftField() { kind.matches("field") }
|
||||
ThriftField() { kind.matches("field") }
|
||||
|
||||
override ThriftElement getNameElement() { result = this.getChild(4) }
|
||||
override ThriftElement getNameElement() { result = this.getChild(4) }
|
||||
|
||||
ThriftType getType() { result = this.getChild(2) }
|
||||
ThriftType getType() { result = this.getChild(2) }
|
||||
}
|
||||
|
||||
class ThriftStruct extends ThriftNamedElement {
|
||||
ThriftStruct() { kind.matches("struct") }
|
||||
ThriftStruct() { kind.matches("struct") }
|
||||
|
||||
override ThriftElement getNameElement() { result = this.getChild(0).getChild(0) }
|
||||
override ThriftElement getNameElement() { result = this.getChild(0).getChild(0) }
|
||||
|
||||
ThriftField getMember(int n) { result = this.getChild(n + 1) }
|
||||
ThriftField getMember(int n) { result = this.getChild(n + 1) }
|
||||
|
||||
ThriftField getAMember() { result = this.getMember(_) }
|
||||
ThriftField getAMember() { result = this.getMember(_) }
|
||||
}
|
||||
|
||||
class ThriftException extends ThriftNamedElement {
|
||||
ThriftException() { kind.matches("exception") }
|
||||
ThriftException() { kind.matches("exception") }
|
||||
|
||||
override ThriftElement getNameElement() { result = this.getChild(0).getChild(0) }
|
||||
override ThriftElement getNameElement() { result = this.getChild(0).getChild(0) }
|
||||
|
||||
ThriftField getMember(int n) { result = this.getChild(n + 1) }
|
||||
ThriftField getMember(int n) { result = this.getChild(n + 1) }
|
||||
|
||||
ThriftField getAMember() { result = this.getMember(_) }
|
||||
ThriftField getAMember() { result = this.getMember(_) }
|
||||
}
|
||||
|
||||
class ThriftThrows extends ThriftElement {
|
||||
ThriftThrows() { kind.matches("throws") }
|
||||
ThriftThrows() { kind.matches("throws") }
|
||||
|
||||
ThriftField getAThrows() { result = this.getChild(_) }
|
||||
ThriftField getAThrows() { result = this.getChild(_) }
|
||||
}
|
||||
|
||||
/** A parse tree element that holds a primitive value */
|
||||
class ThriftValue extends ThriftElement {
|
||||
ThriftValue() { exists(this.getValue()) }
|
||||
ThriftValue() { exists(this.getValue()) }
|
||||
|
||||
override string toString() { result = this.getKind() + " " + this.getValue() }
|
||||
override string toString() { result = this.getKind() + " " + this.getValue() }
|
||||
}
|
||||
|
||||
86
python/ql/src/external/VCS.qll
vendored
86
python/ql/src/external/VCS.qll
vendored
@@ -1,77 +1,79 @@
|
||||
import python
|
||||
|
||||
class Commit extends @svnentry {
|
||||
Commit() {
|
||||
svnaffectedfiles(this, _, _) and
|
||||
exists(date svnDate, date snapshotDate |
|
||||
svnentries(this, _, _, svnDate, _) and
|
||||
snapshotDate(snapshotDate) and
|
||||
svnDate <= snapshotDate
|
||||
)
|
||||
}
|
||||
Commit() {
|
||||
svnaffectedfiles(this, _, _) and
|
||||
exists(date svnDate, date snapshotDate |
|
||||
svnentries(this, _, _, svnDate, _) and
|
||||
snapshotDate(snapshotDate) and
|
||||
svnDate <= snapshotDate
|
||||
)
|
||||
}
|
||||
|
||||
/** Gets a textual representation of this element. */
|
||||
string toString() { result = this.getRevisionName() }
|
||||
/** Gets a textual representation of this element. */
|
||||
string toString() { result = this.getRevisionName() }
|
||||
|
||||
string getRevisionName() { svnentries(this, result, _, _, _) }
|
||||
string getRevisionName() { svnentries(this, result, _, _, _) }
|
||||
|
||||
string getAuthor() { svnentries(this, _, result, _, _) }
|
||||
string getAuthor() { svnentries(this, _, result, _, _) }
|
||||
|
||||
date getDate() { svnentries(this, _, _, result, _) }
|
||||
date getDate() { svnentries(this, _, _, result, _) }
|
||||
|
||||
int getChangeSize() { svnentries(this, _, _, _, result) }
|
||||
int getChangeSize() { svnentries(this, _, _, _, result) }
|
||||
|
||||
string getMessage() { svnentrymsg(this, result) }
|
||||
string getMessage() { svnentrymsg(this, result) }
|
||||
|
||||
string getAnAffectedFilePath(string action) {
|
||||
exists(File rawFile | svnaffectedfiles(this, rawFile, action) | result = rawFile.getAbsolutePath())
|
||||
}
|
||||
string getAnAffectedFilePath(string action) {
|
||||
exists(File rawFile | svnaffectedfiles(this, rawFile, action) |
|
||||
result = rawFile.getAbsolutePath()
|
||||
)
|
||||
}
|
||||
|
||||
string getAnAffectedFilePath() { result = getAnAffectedFilePath(_) }
|
||||
string getAnAffectedFilePath() { result = getAnAffectedFilePath(_) }
|
||||
|
||||
File getAnAffectedFile(string action) { svnaffectedfiles(this, result, action) }
|
||||
File getAnAffectedFile(string action) { svnaffectedfiles(this, result, action) }
|
||||
|
||||
File getAnAffectedFile() { exists(string action | result = this.getAnAffectedFile(action)) }
|
||||
File getAnAffectedFile() { exists(string action | result = this.getAnAffectedFile(action)) }
|
||||
|
||||
predicate isRecent() { recentCommit(this) }
|
||||
predicate isRecent() { recentCommit(this) }
|
||||
|
||||
int daysToNow() {
|
||||
exists(date now | snapshotDate(now) | result = getDate().daysTo(now) and result >= 0)
|
||||
}
|
||||
int daysToNow() {
|
||||
exists(date now | snapshotDate(now) | result = getDate().daysTo(now) and result >= 0)
|
||||
}
|
||||
|
||||
int getRecentAdditionsForFile(File f) { svnchurn(this, f, result, _) }
|
||||
int getRecentAdditionsForFile(File f) { svnchurn(this, f, result, _) }
|
||||
|
||||
int getRecentDeletionsForFile(File f) { svnchurn(this, f, _, result) }
|
||||
int getRecentDeletionsForFile(File f) { svnchurn(this, f, _, result) }
|
||||
|
||||
int getRecentChurnForFile(File f) {
|
||||
result = getRecentAdditionsForFile(f) + getRecentDeletionsForFile(f)
|
||||
}
|
||||
int getRecentChurnForFile(File f) {
|
||||
result = getRecentAdditionsForFile(f) + getRecentDeletionsForFile(f)
|
||||
}
|
||||
}
|
||||
|
||||
class Author extends string {
|
||||
Author() { exists(Commit e | this = e.getAuthor()) }
|
||||
Author() { exists(Commit e | this = e.getAuthor()) }
|
||||
|
||||
Commit getACommit() { result.getAuthor() = this }
|
||||
Commit getACommit() { result.getAuthor() = this }
|
||||
|
||||
File getAnEditedFile() { result = this.getACommit().getAnAffectedFile() }
|
||||
File getAnEditedFile() { result = this.getACommit().getAnAffectedFile() }
|
||||
}
|
||||
|
||||
predicate recentCommit(Commit e) {
|
||||
exists(date snapshotDate, date commitDate, int days |
|
||||
snapshotDate(snapshotDate) and
|
||||
e.getDate() = commitDate and
|
||||
days = commitDate.daysTo(snapshotDate) and
|
||||
days >= 0 and
|
||||
days <= 60
|
||||
)
|
||||
exists(date snapshotDate, date commitDate, int days |
|
||||
snapshotDate(snapshotDate) and
|
||||
e.getDate() = commitDate and
|
||||
days = commitDate.daysTo(snapshotDate) and
|
||||
days >= 0 and
|
||||
days <= 60
|
||||
)
|
||||
}
|
||||
|
||||
date firstChange(File f) {
|
||||
result = min(Commit e, date toMin | f = e.getAnAffectedFile() and toMin = e.getDate() | toMin)
|
||||
result = min(Commit e, date toMin | f = e.getAnAffectedFile() and toMin = e.getDate() | toMin)
|
||||
}
|
||||
|
||||
predicate firstCommit(Commit e) {
|
||||
not exists(File f | f = e.getAnAffectedFile() | firstChange(f) < e.getDate())
|
||||
not exists(File f | f = e.getAnAffectedFile() | firstChange(f) < e.getDate())
|
||||
}
|
||||
|
||||
predicate artificialChange(Commit e) { firstCommit(e) or e.getChangeSize() >= 50000 }
|
||||
|
||||
Reference in New Issue
Block a user