Skip to content

Commit 072a180

Browse files
committed
Util: add AlertSuppression.qll
1 parent e45edcc commit 072a180

File tree

1 file changed

+109
-0
lines changed

1 file changed

+109
-0
lines changed
Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
signature class SingleLineComment {
2+
string toString();
3+
4+
predicate hasLocationInfo(
5+
string filepath, int startline, int startcolumn, int endline, int endcolumn
6+
);
7+
8+
string getText();
9+
}
10+
11+
/**
12+
* Constructs an alert suppression query.
13+
*/
14+
module Make<SingleLineComment Comment> {
15+
/**
16+
* An alert suppression comment.
17+
*/
18+
abstract class SuppressionComment instanceof Comment {
19+
/**
20+
* Gets the text of this suppression comment.
21+
*/
22+
string getText() { result = super.getText() }
23+
24+
/**
25+
* Holds if this element is at the specified location.
26+
* The location spans column `startcolumn` of line `startline` to
27+
* column `endcolumn` of line `endline` in file `filepath`.
28+
* For more information, see
29+
* [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/).
30+
*/
31+
predicate hasLocationInfo(
32+
string filepath, int startline, int startcolumn, int endline, int endcolumn
33+
) {
34+
super.hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn)
35+
}
36+
37+
/** Gets the suppression annotation in this comment. */
38+
abstract string getAnnotation();
39+
40+
/**
41+
* Holds if this comment applies to the range from column `startcolumn` of line `startline`
42+
* to column `endcolumn` of line `endline` in file `filepath`.
43+
*/
44+
abstract predicate covers(
45+
string filepath, int startline, int startcolumn, int endline, int endcolumn
46+
);
47+
48+
/** Gets the scope of this suppression. */
49+
SuppressionScope getScope() { this = result.getSuppressionComment() }
50+
51+
/** Gets a textual representation of this element. */
52+
string toString() { result = super.toString() }
53+
}
54+
55+
private class LgtmSuppressionComment extends SuppressionComment {
56+
private string annotation;
57+
58+
LgtmSuppressionComment() {
59+
exists(string text | text = this.(Comment).getText() |
60+
// match `lgtm[...]` anywhere in the comment
61+
annotation = text.regexpFind("(?i)\\blgtm\\s*\\[[^\\]]*\\]", _, _)
62+
or
63+
// match `lgtm` at the start of the comment and after semicolon
64+
annotation = text.regexpFind("(?i)(?<=^|;)\\s*lgtm(?!\\B|\\s*\\[)", _, _).trim()
65+
)
66+
}
67+
68+
override string getAnnotation() { result = annotation }
69+
70+
override predicate covers(
71+
string filepath, int startline, int startcolumn, int endline, int endcolumn
72+
) {
73+
this.hasLocationInfo(filepath, startline, _, endline, endcolumn) and
74+
startcolumn = 1
75+
}
76+
}
77+
78+
/**
79+
* The scope of an alert suppression comment.
80+
*/
81+
private class SuppressionScope instanceof SuppressionComment {
82+
/** Gets a suppression comment with this scope. */
83+
SuppressionComment getSuppressionComment() { result = this }
84+
85+
/**
86+
* Holds if this element is at the specified location.
87+
* The location spans column `startcolumn` of line `startline` to
88+
* column `endcolumn` of line `endline` in file `filepath`.
89+
* For more information, see
90+
* [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/).
91+
*/
92+
predicate hasLocationInfo(
93+
string filepath, int startline, int startcolumn, int endline, int endcolumn
94+
) {
95+
this.(SuppressionComment).covers(filepath, startline, startcolumn, endline, endcolumn)
96+
}
97+
98+
/** Gets a textual representation of this element. */
99+
string toString() { result = "suppression range" }
100+
}
101+
102+
query predicate suppressions(
103+
SuppressionComment c, string text, string annotation, SuppressionScope scope
104+
) {
105+
text = c.getText() and // text of suppression comment (excluding delimiters)
106+
annotation = c.getAnnotation() and // text of suppression annotation
107+
scope = c.getScope() // scope of suppression
108+
}
109+
}

0 commit comments

Comments
 (0)