Skip to content

Commit 139e09d

Browse files
committed
C#: Add diagnostic query indicating low database quality
1 parent e222b49 commit 139e09d

File tree

8 files changed

+128
-66
lines changed

8 files changed

+128
-66
lines changed
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
diagnosticAttributes
2+
| Scanning C# code completed successfully, but the scan encountered issues. This may be caused by problems identifying dependencies or use of generated source code, among other reasons -- see other CodeQL diagnostics reported on the CodeQL status page for more details of possible causes. Addressing these warnings is advisable to avoid false-positive or missing results. If they cannot be addressed, consider scanning C# using either the `autobuild` or `manual` [build modes](https://docs.github.com/en/code-security/code-scanning/creating-an-advanced-setup-for-code-scanning/codeql-code-scanning-for-compiled-languages#comparison-of-the-build-modes). | visibilityCliSummaryTable | true |
3+
| Scanning C# code completed successfully, but the scan encountered issues. This may be caused by problems identifying dependencies or use of generated source code, among other reasons -- see other CodeQL diagnostics reported on the CodeQL status page for more details of possible causes. Addressing these warnings is advisable to avoid false-positive or missing results. If they cannot be addressed, consider scanning C# using either the `autobuild` or `manual` [build modes](https://docs.github.com/en/code-security/code-scanning/creating-an-advanced-setup-for-code-scanning/codeql-code-scanning-for-compiled-languages#comparison-of-the-build-modes). | visibilityStatusPage | true |
4+
| Scanning C# code completed successfully, but the scan encountered issues. This may be caused by problems identifying dependencies or use of generated source code, among other reasons -- see other CodeQL diagnostics reported on the CodeQL status page for more details of possible causes. Addressing these warnings is advisable to avoid false-positive or missing results. If they cannot be addressed, consider scanning C# using either the `autobuild` or `manual` [build modes](https://docs.github.com/en/code-security/code-scanning/creating-an-advanced-setup-for-code-scanning/codeql-code-scanning-for-compiled-languages#comparison-of-the-build-modes). | visibilityTelemetry | true |
5+
#select
6+
| Scanning C# code completed successfully, but the scan encountered issues. This may be caused by problems identifying dependencies or use of generated source code, among other reasons -- see other CodeQL diagnostics reported on the CodeQL status page for more details of possible causes. Addressing these warnings is advisable to avoid false-positive or missing results. If they cannot be addressed, consider scanning C# using either the `autobuild` or `manual` [build modes](https://docs.github.com/en/code-security/code-scanning/creating-an-advanced-setup-for-code-scanning/codeql-code-scanning-for-compiled-languages#comparison-of-the-build-modes). | Scanning C# code completed successfully, but the scan encountered issues. This may be caused by problems identifying dependencies or use of generated source code, among other reasons -- see other CodeQL diagnostics reported on the CodeQL status page for more details of possible causes. Addressing these warnings is advisable to avoid false-positive or missing results. If they cannot be addressed, consider scanning C# using either the `autobuild` or `manual` [build modes](https://docs.github.com/en/code-security/code-scanning/creating-an-advanced-setup-for-code-scanning/codeql-code-scanning-for-compiled-languages#comparison-of-the-build-modes). | 1 |
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Telemetry/DatabaseQualityDiagnostics.ql
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
diagnosticAttributes
2+
#select
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Telemetry/DatabaseQualityDiagnostics.ql
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
dependencies:
22
codeql/csharp-all: '*'
3+
codeql/csharp-queries: '*'
34
warnOnImplicitThis: true
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
/**
2+
* Provides database quality statistics that are reported by csharp/telemetry/extractor-information
3+
* and perhaps warned about by csharp/diagnostics/database-quality.
4+
*/
5+
6+
import csharp
7+
8+
signature module StatsSig {
9+
int getNumberOfOk();
10+
11+
int getNumberOfNotOk();
12+
13+
string getOkText();
14+
15+
string getNotOkText();
16+
}
17+
18+
module ReportStats<StatsSig Stats> {
19+
predicate numberOfOk(string key, int value) {
20+
value = Stats::getNumberOfOk() and
21+
key = "Number of " + Stats::getOkText()
22+
}
23+
24+
predicate numberOfNotOk(string key, int value) {
25+
value = Stats::getNumberOfNotOk() and
26+
key = "Number of " + Stats::getNotOkText()
27+
}
28+
29+
predicate percentageOfOk(string key, float value) {
30+
value = Stats::getNumberOfOk() * 100.0 / (Stats::getNumberOfOk() + Stats::getNumberOfNotOk()) and
31+
key = "Percentage of " + Stats::getOkText()
32+
}
33+
}
34+
35+
module CallTargetStats implements StatsSig {
36+
int getNumberOfOk() { result = count(Call c | exists(c.getTarget())) }
37+
38+
int getNumberOfNotOk() {
39+
result =
40+
count(Call c |
41+
not exists(c.getTarget()) and
42+
not c instanceof DelegateCall and
43+
not c instanceof DynamicExpr
44+
)
45+
}
46+
47+
string getOkText() { result = "calls with call target" }
48+
49+
string getNotOkText() { result = "calls with missing call target" }
50+
}
51+
52+
private class SourceExpr extends Expr {
53+
SourceExpr() { this.getFile().fromSource() }
54+
}
55+
56+
private predicate hasGoodType(Expr e) {
57+
exists(e.getType()) and not e.getType() instanceof UnknownType
58+
}
59+
60+
module ExprTypeStats implements StatsSig {
61+
int getNumberOfOk() { result = count(SourceExpr e | hasGoodType(e)) }
62+
63+
int getNumberOfNotOk() { result = count(SourceExpr e | not hasGoodType(e)) }
64+
65+
string getOkText() { result = "expressions with known type" }
66+
67+
string getNotOkText() { result = "expressions with unknown type" }
68+
}
69+
70+
module CallTargetStatsReport = ReportStats<CallTargetStats>;
71+
72+
module ExprTypeStatsReport = ReportStats<ExprTypeStats>;
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
/**
2+
* @name Low C# analysis quality
3+
* @description Low C# analysis quality
4+
* @kind diagnostic
5+
* @id csharp/diagnostic/database-quality
6+
*/
7+
8+
import csharp
9+
import DatabaseQuality
10+
11+
private newtype TDbQualityDiagnostic =
12+
TTheDbQualityDiagnostic() {
13+
exists(float percentageGood |
14+
CallTargetStatsReport::percentageOfOk(_, percentageGood)
15+
or
16+
ExprTypeStatsReport::percentageOfOk(_, percentageGood)
17+
|
18+
percentageGood < 95
19+
)
20+
}
21+
22+
class DbQualityDiagnostic extends TDbQualityDiagnostic {
23+
string toString() {
24+
result =
25+
"Scanning C# code completed successfully, but the scan encountered issues. " +
26+
"This may be caused by problems identifying dependencies or use of generated source code, among other reasons -- "
27+
+
28+
"see other CodeQL diagnostics reported on the CodeQL status page for more details of possible causes. "
29+
+
30+
"Addressing these warnings is advisable to avoid false-positive or missing results. If they cannot be addressed, consider scanning C# "
31+
+
32+
"using either the `autobuild` or `manual` [build modes](https://docs.github.com/en/code-security/code-scanning/creating-an-advanced-setup-for-code-scanning/codeql-code-scanning-for-compiled-languages#comparison-of-the-build-modes)."
33+
}
34+
}
35+
36+
query predicate diagnosticAttributes(DbQualityDiagnostic e, string key, string value) {
37+
e = e and // Quieten warning about unconstrained 'e'
38+
key = ["visibilityCliSummaryTable", "visibilityTelemetry", "visibilityStatusPage"] and
39+
value = "true"
40+
}
41+
42+
from DbQualityDiagnostic d
43+
select d, d.toString(), 1
44+
/* Warning severity */

csharp/ql/src/Telemetry/ExtractorInformation.ql

Lines changed: 1 addition & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88

99
import csharp
1010
import semmle.code.csharp.commons.Diagnostics
11+
import DatabaseQuality
1112

1213
predicate compilationInfo(string key, float value) {
1314
not key.matches("Compiler diagnostic count for%") and
@@ -90,68 +91,6 @@ predicate extractionIsStandalone(string key, int value) {
9091
key = "Is extracted with build-mode set to 'none'"
9192
}
9293

93-
signature module StatsSig {
94-
int getNumberOfOk();
95-
96-
int getNumberOfNotOk();
97-
98-
string getOkText();
99-
100-
string getNotOkText();
101-
}
102-
103-
module ReportStats<StatsSig Stats> {
104-
predicate numberOfOk(string key, int value) {
105-
value = Stats::getNumberOfOk() and
106-
key = "Number of " + Stats::getOkText()
107-
}
108-
109-
predicate numberOfNotOk(string key, int value) {
110-
value = Stats::getNumberOfNotOk() and
111-
key = "Number of " + Stats::getNotOkText()
112-
}
113-
114-
predicate percentageOfOk(string key, float value) {
115-
value = Stats::getNumberOfOk() * 100.0 / (Stats::getNumberOfOk() + Stats::getNumberOfNotOk()) and
116-
key = "Percentage of " + Stats::getOkText()
117-
}
118-
}
119-
120-
module CallTargetStats implements StatsSig {
121-
int getNumberOfOk() { result = count(Call c | exists(c.getTarget())) }
122-
123-
int getNumberOfNotOk() {
124-
result =
125-
count(Call c |
126-
not exists(c.getTarget()) and
127-
not c instanceof DelegateCall and
128-
not c instanceof DynamicExpr
129-
)
130-
}
131-
132-
string getOkText() { result = "calls with call target" }
133-
134-
string getNotOkText() { result = "calls with missing call target" }
135-
}
136-
137-
private class SourceExpr extends Expr {
138-
SourceExpr() { this.getFile().fromSource() }
139-
}
140-
141-
private predicate hasGoodType(Expr e) {
142-
exists(e.getType()) and not e.getType() instanceof UnknownType
143-
}
144-
145-
module ExprTypeStats implements StatsSig {
146-
int getNumberOfOk() { result = count(SourceExpr e | hasGoodType(e)) }
147-
148-
int getNumberOfNotOk() { result = count(SourceExpr e | not hasGoodType(e)) }
149-
150-
string getOkText() { result = "expressions with known type" }
151-
152-
string getNotOkText() { result = "expressions with unknown type" }
153-
}
154-
15594
module TypeMentionTypeStats implements StatsSig {
15695
int getNumberOfOk() { result = count(TypeMention t | not t.getType() instanceof UnknownType) }
15796

@@ -182,10 +121,6 @@ module ExprStats implements StatsSig {
182121
string getNotOkText() { result = "expressions with unknown kind" }
183122
}
184123

185-
module CallTargetStatsReport = ReportStats<CallTargetStats>;
186-
187-
module ExprTypeStatsReport = ReportStats<ExprTypeStats>;
188-
189124
module TypeMentionTypeStatsReport = ReportStats<TypeMentionTypeStats>;
190125

191126
module AccessTargetStatsReport = ReportStats<AccessTargetStats>;

0 commit comments

Comments
 (0)