Merge pull request #297 from github/aibaars/alert-suppression

Alert suppression and file classifier query
This commit is contained in:
Arthur Baars
2021-09-23 15:37:19 +02:00
committed by GitHub
8 changed files with 251 additions and 0 deletions

View File

@@ -0,0 +1,43 @@
/** Provides classes for detecting generated code. */
private import ruby
private import codeql.ruby.ast.internal.TreeSitter
/** A source file that contains generated code. */
abstract class GeneratedCodeFile extends RubyFile { }
/** A file contining comments suggesting it contains generated code. */
class GeneratedCommentFile extends GeneratedCodeFile {
GeneratedCommentFile() { this = any(GeneratedCodeComment c).getLocation().getFile() }
}
/** A comment line that indicates generated code. */
abstract class GeneratedCodeComment extends Ruby::Comment { }
/**
* A generic comment line that suggests that the file is generated.
*/
class GenericGeneratedCodeComment extends GeneratedCodeComment {
GenericGeneratedCodeComment() {
exists(string line, string entity, string was, string automatically | line = getValue() |
entity = "file|class|art[ei]fact|module|script" and
was = "was|is|has been" and
automatically = "automatically |mechanically |auto[- ]?" and
line.regexpMatch("(?i).*\\bThis (" + entity + ") (" + was + ") (" + automatically +
")?generated\\b.*")
)
}
}
/** A comment warning against modifications. */
class DontModifyMarkerComment extends GeneratedCodeComment {
DontModifyMarkerComment() {
exists(string line | line = getValue() |
line.regexpMatch("(?i).*\\bGenerated by\\b.*\\bDo not edit\\b.*") or
line.regexpMatch("(?i).*\\bAny modifications to this file will be lost\\b.*")
)
}
}
/** Holds if `file` looks like it contains generated code. */
predicate isGeneratedCode(GeneratedCodeFile file) { any() }

View File

@@ -0,0 +1,82 @@
/**
* @name Alert suppression
* @description Generates information about alert suppressions.
* @kind alert-suppression
* @id rb/alert-suppression
*/
import ruby
import codeql.ruby.ast.internal.TreeSitter
/**
* An alert suppression comment.
*/
class SuppressionComment extends Ruby::Comment {
string annotation;
SuppressionComment() {
// suppression comments must be single-line
this.getLocation().getStartLine() = this.getLocation().getEndLine() and
exists(string text | text = commentText(this) |
// match `lgtm[...]` anywhere in the comment
annotation = text.regexpFind("(?i)\\blgtm\\s*\\[[^\\]]*\\]", _, _)
or
// match `lgtm` at the start of the comment and after semicolon
annotation = text.regexpFind("(?i)(?<=^|;)\\s*lgtm(?!\\B|\\s*\\[)", _, _).trim()
)
}
/**
* Gets the text of this suppression comment.
*/
string getText() { result = commentText(this) }
/** Gets the suppression annotation in this comment. */
string getAnnotation() { result = annotation }
/**
* Holds if this comment applies to the range from column `startcolumn` of line `startline`
* to column `endcolumn` of line `endline` in file `filepath`.
*/
predicate covers(string filepath, int startline, int startcolumn, int endline, int endcolumn) {
this.getLocation().hasLocationInfo(filepath, startline, _, endline, endcolumn) and
startcolumn = 1
}
/** Gets the scope of this suppression. */
SuppressionScope getScope() { this = result.getSuppressionComment() }
}
private string commentText(Ruby::Comment comment) { result = comment.getValue().suffix(1) }
/**
* The scope of an alert suppression comment.
*/
class SuppressionScope extends @ruby_token_comment {
SuppressionScope() { this instanceof SuppressionComment }
/** Gets a suppression comment with this scope. */
SuppressionComment getSuppressionComment() { result = this }
/**
* 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
) {
this.(SuppressionComment).covers(filepath, startline, startcolumn, endline, endcolumn)
}
/** Gets a textual representation of this element. */
string toString() { result = "suppression range" }
}
from SuppressionComment c
select c, // suppression comment
c.getText(), // text of suppression comment (excluding delimiters)
c.getAnnotation(), // text of suppression annotation
c.getScope() // scope of suppression

View File

@@ -0,0 +1,20 @@
/**
* @name Classify files
* @description This query produces a list of all files in a database
* that are classified as generated code or test code.
*
* Used by LGTM.
* @kind file-classifier
* @id rb/file-classifier
*/
import ruby
import codeql.ruby.filters.GeneratedCode
predicate classify(File f, string category) {
f instanceof GeneratedCodeFile and category = "generated"
}
from File f, string category
where classify(f, category)
select f, category

View File

@@ -0,0 +1 @@
TestWindows.java eol=crlf

View File

@@ -0,0 +1,48 @@
| Test.rb:1:16:1:21 | # lgtm | lgtm | lgtm | Test.rb:1:1:1:21 | suppression range |
| Test.rb:2:1:2:32 | # lgtm[rb/confusing-method-name] | lgtm[rb/confusing-method-name] | lgtm[rb/confusing-method-name] | Test.rb:2:1:2:32 | suppression range |
| Test.rb:3:1:3:65 | # lgtm[rb/confusing-method-name, rb/non-short-circuit-evaluation] | lgtm[rb/confusing-method-name, rb/non-short-circuit-evaluation] | lgtm[rb/confusing-method-name, rb/non-short-circuit-evaluation] | Test.rb:3:1:3:65 | suppression range |
| Test.rb:4:1:4:23 | # lgtm[@tag:exceptions] | lgtm[@tag:exceptions] | lgtm[@tag:exceptions] | Test.rb:4:1:4:23 | suppression range |
| Test.rb:5:1:5:48 | # lgtm[@tag:exceptions,rb/confusing-method-name] | lgtm[@tag:exceptions,rb/confusing-method-name] | lgtm[@tag:exceptions,rb/confusing-method-name] | Test.rb:5:1:5:48 | suppression range |
| Test.rb:6:1:6:27 | # lgtm[@expires:2017-06-11] | lgtm[@expires:2017-06-11] | lgtm[@expires:2017-06-11] | Test.rb:6:1:6:27 | suppression range |
| Test.rb:7:1:7:78 | # lgtm[rb/confusing-method-name] does not seem confusing despite alert by lgtm | lgtm[rb/confusing-method-name] does not seem confusing despite alert by lgtm | lgtm[rb/confusing-method-name] | Test.rb:7:1:7:78 | suppression range |
| Test.rb:8:1:8:17 | # lgtm: blah blah | lgtm: blah blah | lgtm | Test.rb:8:1:8:17 | suppression range |
| Test.rb:9:1:9:31 | # lgtm blah blah #falsepositive | lgtm blah blah #falsepositive | lgtm | Test.rb:9:1:9:31 | suppression range |
| Test.rb:10:1:10:33 | #lgtm [rb/confusing-method-name] | lgtm [rb/confusing-method-name] | lgtm [rb/confusing-method-name] | Test.rb:10:1:10:33 | suppression range |
| Test.rb:11:1:11:8 | # lgtm[] | lgtm[] | lgtm[] | Test.rb:11:1:11:8 | suppression range |
| Test.rb:13:1:13:5 | #lgtm | lgtm | lgtm | Test.rb:13:1:13:5 | suppression range |
| Test.rb:14:1:14:6 | #\tlgtm | \tlgtm | lgtm | Test.rb:14:1:14:6 | suppression range |
| Test.rb:15:1:15:33 | # lgtm\t[rb/confusing-method-name] | lgtm\t[rb/confusing-method-name] | lgtm\t[rb/confusing-method-name] | Test.rb:15:1:15:33 | suppression range |
| Test.rb:18:1:18:11 | # foo; lgtm | foo; lgtm | lgtm | Test.rb:18:1:18:11 | suppression range |
| Test.rb:19:1:19:37 | # foo; lgtm[rb/confusing-method-name] | foo; lgtm[rb/confusing-method-name] | lgtm[rb/confusing-method-name] | Test.rb:19:1:19:37 | suppression range |
| Test.rb:21:1:21:36 | # foo lgtm[rb/confusing-method-name] | foo lgtm[rb/confusing-method-name] | lgtm[rb/confusing-method-name] | Test.rb:21:1:21:36 | suppression range |
| Test.rb:23:1:23:40 | # foo lgtm[rb/confusing-method-name] bar | foo lgtm[rb/confusing-method-name] bar | lgtm[rb/confusing-method-name] | Test.rb:23:1:23:40 | suppression range |
| Test.rb:24:1:24:7 | # LGTM! | LGTM! | LGTM | Test.rb:24:1:24:7 | suppression range |
| Test.rb:25:1:25:32 | # LGTM[rb/confusing-method-name] | LGTM[rb/confusing-method-name] | LGTM[rb/confusing-method-name] | Test.rb:25:1:25:32 | suppression range |
| Test.rb:26:1:26:73 | #lgtm[rb/confusing-method-name] and lgtm[rb/non-short-circuit-evaluation] | lgtm[rb/confusing-method-name] and lgtm[rb/non-short-circuit-evaluation] | lgtm[rb/confusing-method-name] | Test.rb:26:1:26:73 | suppression range |
| Test.rb:26:1:26:73 | #lgtm[rb/confusing-method-name] and lgtm[rb/non-short-circuit-evaluation] | lgtm[rb/confusing-method-name] and lgtm[rb/non-short-circuit-evaluation] | lgtm[rb/non-short-circuit-evaluation] | Test.rb:26:1:26:73 | suppression range |
| Test.rb:27:1:27:37 | #lgtm[rb/confusing-method-name]; lgtm | lgtm[rb/confusing-method-name]; lgtm | lgtm | Test.rb:27:1:27:37 | suppression range |
| Test.rb:27:1:27:37 | #lgtm[rb/confusing-method-name]; lgtm | lgtm[rb/confusing-method-name]; lgtm | lgtm[rb/confusing-method-name] | Test.rb:27:1:27:37 | suppression range |
| TestWindows.rb:1:23:1:29 | # lgtm\r | lgtm\r | lgtm | TestWindows.rb:1:1:1:29 | suppression range |
| TestWindows.rb:2:1:2:33 | # lgtm[rb/confusing-method-name]\r | lgtm[rb/confusing-method-name]\r | lgtm[rb/confusing-method-name] | TestWindows.rb:2:1:2:33 | suppression range |
| TestWindows.rb:3:1:3:66 | # lgtm[rb/confusing-method-name, rb/non-short-circuit-evaluation]\r | lgtm[rb/confusing-method-name, rb/non-short-circuit-evaluation]\r | lgtm[rb/confusing-method-name, rb/non-short-circuit-evaluation] | TestWindows.rb:3:1:3:66 | suppression range |
| TestWindows.rb:4:1:4:24 | # lgtm[@tag:exceptions]\r | lgtm[@tag:exceptions]\r | lgtm[@tag:exceptions] | TestWindows.rb:4:1:4:24 | suppression range |
| TestWindows.rb:5:1:5:49 | # lgtm[@tag:exceptions,rb/confusing-method-name]\r | lgtm[@tag:exceptions,rb/confusing-method-name]\r | lgtm[@tag:exceptions,rb/confusing-method-name] | TestWindows.rb:5:1:5:49 | suppression range |
| TestWindows.rb:6:1:6:28 | # lgtm[@expires:2017-06-11]\r | lgtm[@expires:2017-06-11]\r | lgtm[@expires:2017-06-11] | TestWindows.rb:6:1:6:28 | suppression range |
| TestWindows.rb:7:1:7:79 | # lgtm[rb/confusing-method-name] does not seem confusing despite alert by lgtm\r | lgtm[rb/confusing-method-name] does not seem confusing despite alert by lgtm\r | lgtm[rb/confusing-method-name] | TestWindows.rb:7:1:7:79 | suppression range |
| TestWindows.rb:8:1:8:18 | # lgtm: blah blah\r | lgtm: blah blah\r | lgtm | TestWindows.rb:8:1:8:18 | suppression range |
| TestWindows.rb:9:1:9:32 | # lgtm blah blah #falsepositive\r | lgtm blah blah #falsepositive\r | lgtm | TestWindows.rb:9:1:9:32 | suppression range |
| TestWindows.rb:10:1:10:34 | #lgtm [rb/confusing-method-name]\r | lgtm [rb/confusing-method-name]\r | lgtm [rb/confusing-method-name] | TestWindows.rb:10:1:10:34 | suppression range |
| TestWindows.rb:11:1:11:9 | # lgtm[]\r | lgtm[]\r | lgtm[] | TestWindows.rb:11:1:11:9 | suppression range |
| TestWindows.rb:13:1:13:6 | #lgtm\r | lgtm\r | lgtm | TestWindows.rb:13:1:13:6 | suppression range |
| TestWindows.rb:14:1:14:7 | #\tlgtm\r | \tlgtm\r | lgtm | TestWindows.rb:14:1:14:7 | suppression range |
| TestWindows.rb:15:1:15:34 | # lgtm\t[rb/confusing-method-name]\r | lgtm\t[rb/confusing-method-name]\r | lgtm\t[rb/confusing-method-name] | TestWindows.rb:15:1:15:34 | suppression range |
| TestWindows.rb:18:1:18:12 | # foo; lgtm\r | foo; lgtm\r | lgtm | TestWindows.rb:18:1:18:12 | suppression range |
| TestWindows.rb:19:1:19:38 | # foo; lgtm[rb/confusing-method-name]\r | foo; lgtm[rb/confusing-method-name]\r | lgtm[rb/confusing-method-name] | TestWindows.rb:19:1:19:38 | suppression range |
| TestWindows.rb:21:1:21:37 | # foo lgtm[rb/confusing-method-name]\r | foo lgtm[rb/confusing-method-name]\r | lgtm[rb/confusing-method-name] | TestWindows.rb:21:1:21:37 | suppression range |
| TestWindows.rb:23:1:23:41 | # foo lgtm[rb/confusing-method-name] bar\r | foo lgtm[rb/confusing-method-name] bar\r | lgtm[rb/confusing-method-name] | TestWindows.rb:23:1:23:41 | suppression range |
| TestWindows.rb:24:1:24:8 | # LGTM!\r | LGTM!\r | LGTM | TestWindows.rb:24:1:24:8 | suppression range |
| TestWindows.rb:25:1:25:33 | # LGTM[rb/confusing-method-name]\r | LGTM[rb/confusing-method-name]\r | LGTM[rb/confusing-method-name] | TestWindows.rb:25:1:25:33 | suppression range |
| TestWindows.rb:26:1:26:74 | #lgtm[rb/confusing-method-name] and lgtm[rb/non-short-circuit-evaluation]\r | lgtm[rb/confusing-method-name] and lgtm[rb/non-short-circuit-evaluation]\r | lgtm[rb/confusing-method-name] | TestWindows.rb:26:1:26:74 | suppression range |
| TestWindows.rb:26:1:26:74 | #lgtm[rb/confusing-method-name] and lgtm[rb/non-short-circuit-evaluation]\r | lgtm[rb/confusing-method-name] and lgtm[rb/non-short-circuit-evaluation]\r | lgtm[rb/non-short-circuit-evaluation] | TestWindows.rb:26:1:26:74 | suppression range |
| TestWindows.rb:27:1:27:38 | #lgtm[rb/confusing-method-name]; lgtm\r | lgtm[rb/confusing-method-name]; lgtm\r | lgtm | TestWindows.rb:27:1:27:38 | suppression range |
| TestWindows.rb:27:1:27:38 | #lgtm[rb/confusing-method-name]; lgtm\r | lgtm[rb/confusing-method-name]; lgtm\r | lgtm[rb/confusing-method-name] | TestWindows.rb:27:1:27:38 | suppression range |

View File

@@ -0,0 +1 @@
AlertSuppression.ql

View File

@@ -0,0 +1,28 @@
class Test end # lgtm
# lgtm[rb/confusing-method-name]
# lgtm[rb/confusing-method-name, rb/non-short-circuit-evaluation]
# lgtm[@tag:exceptions]
# lgtm[@tag:exceptions,rb/confusing-method-name]
# lgtm[@expires:2017-06-11]
# lgtm[rb/confusing-method-name] does not seem confusing despite alert by lgtm
# lgtm: blah blah
# lgtm blah blah #falsepositive
#lgtm [rb/confusing-method-name]
# lgtm[]
# lgtmfoo
#lgtm
# lgtm
# lgtm [rb/confusing-method-name]
# foolgtm[rb/confusing-method-name]
# foolgtm
# foo; lgtm
# foo; lgtm[rb/confusing-method-name]
# foo lgtm
# foo lgtm[rb/confusing-method-name]
# foo lgtm bar
# foo lgtm[rb/confusing-method-name] bar
# LGTM!
# LGTM[rb/confusing-method-name]
#lgtm[rb/confusing-method-name] and lgtm[rb/non-short-circuit-evaluation]
#lgtm[rb/confusing-method-name]; lgtm

View File

@@ -0,0 +1,28 @@
class TestWindows end # lgtm
# lgtm[rb/confusing-method-name]
# lgtm[rb/confusing-method-name, rb/non-short-circuit-evaluation]
# lgtm[@tag:exceptions]
# lgtm[@tag:exceptions,rb/confusing-method-name]
# lgtm[@expires:2017-06-11]
# lgtm[rb/confusing-method-name] does not seem confusing despite alert by lgtm
# lgtm: blah blah
# lgtm blah blah #falsepositive
#lgtm [rb/confusing-method-name]
# lgtm[]
# lgtmfoo
#lgtm
# lgtm
# lgtm [rb/confusing-method-name]
# foolgtm[rb/confusing-method-name]
# foolgtm
# foo; lgtm
# foo; lgtm[rb/confusing-method-name]
# foo lgtm
# foo lgtm[rb/confusing-method-name]
# foo lgtm bar
# foo lgtm[rb/confusing-method-name] bar
# LGTM!
# LGTM[rb/confusing-method-name]
#lgtm[rb/confusing-method-name] and lgtm[rb/non-short-circuit-evaluation]
#lgtm[rb/confusing-method-name]; lgtm