Skip to content

Commit b3f7a8a

Browse files
authored
Merge pull request #17908 from geoffw0/dfcons
Rust: Expose counts of data flow inconsistencies
2 parents ff80b24 + c8c747a commit b3f7a8a

File tree

8 files changed

+181
-1
lines changed

8 files changed

+181
-1
lines changed

rust/ql/consistency-queries/DataFlowConsistency.ql

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,10 @@
1+
/**
2+
* @name Data flow inconsistencies
3+
* @description Lists the data flow inconsistencies in the database. This query is intended for internal use.
4+
* @kind table
5+
* @id rust/diagnostics/data-flow-consistency
6+
*/
7+
18
import codeql.rust.dataflow.DataFlow::DataFlow as DataFlow
29
private import rust
310
private import codeql.rust.dataflow.internal.DataFlowImpl
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
/**
2+
* @name Data flow inconsistency counts
3+
* @description Counts the number of data flow inconsistencies of each type. This query is intended for internal use.
4+
* @kind diagnostic
5+
* @id rust/diagnostics/data-flow-consistency-counts
6+
*/
7+
8+
private import rust
9+
private import codeql.rust.dataflow.internal.DataFlowImpl
10+
private import codeql.rust.dataflow.internal.TaintTrackingImpl
11+
private import codeql.dataflow.internal.DataFlowImplConsistency
12+
13+
private module Input implements InputSig<Location, RustDataFlow> { }
14+
15+
// see also `rust/diagnostics/data-flow-consistency`, which lists the
16+
// individual inconsistency results.
17+
from string type, int num
18+
where
19+
num =
20+
MakeConsistency<Location, RustDataFlow, RustTaintTracking, Input>::getInconsistencyCounts(type)
21+
select type, num

rust/ql/src/queries/summary/Stats.qll

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,11 @@
33
*/
44

55
import rust
6-
import codeql.rust.AstConsistency as AstConsistency
6+
private import codeql.rust.dataflow.internal.DataFlowImpl
7+
private import codeql.rust.dataflow.internal.TaintTrackingImpl
8+
private import codeql.rust.AstConsistency as AstConsistency
79
private import codeql.rust.controlflow.internal.CfgConsistency as CfgConsistency
10+
private import codeql.dataflow.internal.DataFlowImplConsistency as DataFlowImplConsistency
811

912
/**
1013
* Gets a count of the total number of lines of code in the database.
@@ -31,3 +34,16 @@ int getTotalAstInconsistencies() {
3134
int getTotalCfgInconsistencies() {
3235
result = sum(string type | | CfgConsistency::getCfgInconsistencyCounts(type))
3336
}
37+
38+
private module Input implements DataFlowImplConsistency::InputSig<Location, RustDataFlow> { }
39+
40+
/**
41+
* Gets a count of the total number of data flow inconsistencies in the database.
42+
*/
43+
int getTotalDataFlowInconsistencies() {
44+
result =
45+
sum(string type |
46+
|
47+
DataFlowImplConsistency::MakeConsistency<Location, RustDataFlow, RustTaintTracking, Input>::getInconsistencyCounts(type)
48+
)
49+
}

rust/ql/src/queries/summary/SummaryStats.ql

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,4 +35,6 @@ where
3535
key = "Inconsistencies - AST" and value = getTotalAstInconsistencies()
3636
or
3737
key = "Inconsistencies - CFG" and value = getTotalCfgInconsistencies()
38+
or
39+
key = "Inconsistencies - data flow" and value = getTotalDataFlowInconsistencies()
3840
select key, value
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
| ArgumentNode is missing PostUpdateNode | 0 |
2+
| Call context for isUnreachableInCall is inconsistent with call graph | 0 |
3+
| Call context too large | 0 |
4+
| Call should have one enclosing callable | 7 |
5+
| Callable mismatch for parameter | 0 |
6+
| Lambda call enclosing callable mismatch | 0 |
7+
| Local flow step does not preserve enclosing callable | 0 |
8+
| Missing call for argument node | 0 |
9+
| Multiple calls for argument node | 0 |
10+
| Node and call does not share enclosing callable | 0 |
11+
| Node has multiple PostUpdateNodes | 0 |
12+
| Node should have one enclosing callable | 0 |
13+
| Node should have one location | 0 |
14+
| Node should have one toString | 0 |
15+
| Node should have one type | 0 |
16+
| Node steps to itself | 0 |
17+
| Nodes without location | 0 |
18+
| Non-unique content approximation | 0 |
19+
| Origin of readStep is missing a PostUpdateNode | 0 |
20+
| Parameter node with multiple positions | 0 |
21+
| Parameters with overlapping positions | 0 |
22+
| PostUpdateNode does not share callable with its pre-update node | 0 |
23+
| PostUpdateNode should have one pre-update node | 0 |
24+
| PostUpdateNode should not be the target of local flow | 0 |
25+
| PostUpdateNode should not equal its pre-update node | 0 |
26+
| Read step does not preserve enclosing callable | 0 |
27+
| Speculative step already hasM Model | 0 |
28+
| Store step does not preserve enclosing callable | 0 |
29+
| Type compatibility predicate is not reflexive | 0 |
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
queries/diagnostics/DataFlowConsistencyCounts.ql

rust/ql/test/query-tests/diagnostics/SummaryStats.expected

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,5 +7,6 @@
77
| Files extracted - without errors | 5 |
88
| Inconsistencies - AST | 0 |
99
| Inconsistencies - CFG | 0 |
10+
| Inconsistencies - data flow | 7 |
1011
| Lines of code extracted | 59 |
1112
| Lines of user code extracted | 59 |

shared/dataflow/codeql/dataflow/internal/DataFlowImplConsistency.qll

Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -337,4 +337,107 @@ module MakeConsistency<
337337
)
338338
)
339339
}
340+
341+
/**
342+
* Gets counts of inconsistencies of each type.
343+
*/
344+
int getInconsistencyCounts(string type) {
345+
// total results from all the AST consistency query predicates.
346+
type = "Node should have one enclosing callable" and
347+
result = count(Node n | uniqueEnclosingCallable(n, _))
348+
or
349+
type = "Call should have one enclosing callable" and
350+
result = count(DataFlowCall c | uniqueCallEnclosingCallable(c, _))
351+
or
352+
type = "Node should have one type" and
353+
result = count(Node n | uniqueType(n, _))
354+
or
355+
type = "Node should have one location" and
356+
result = count(Node n | uniqueNodeLocation(n, _))
357+
or
358+
type = "Nodes without location" and
359+
result = count( | missingLocation(_) | 1)
360+
or
361+
type = "Node should have one toString" and
362+
result = count(Node n | uniqueNodeToString(n, _))
363+
or
364+
type = "Callable mismatch for parameter" and
365+
result = count(ParameterNode p | parameterCallable(p, _))
366+
or
367+
type = "Local flow step does not preserve enclosing callable" and
368+
result = count(Node n1, Node n2 | localFlowIsLocal(n1, n2, _))
369+
or
370+
type = "Read step does not preserve enclosing callable" and
371+
result = count(Node n1, Node n2 | readStepIsLocal(n1, n2, _))
372+
or
373+
type = "Store step does not preserve enclosing callable" and
374+
result = count(Node n1, Node n2 | storeStepIsLocal(n1, n2, _))
375+
or
376+
type = "Type compatibility predicate is not reflexive" and
377+
result = count(DataFlowType t | compatibleTypesReflexive(t, _))
378+
or
379+
type = "Call context for isUnreachableInCall is inconsistent with call graph" and
380+
result = count(Node n, DataFlowCall call | unreachableNodeCCtx(n, call, _))
381+
or
382+
type = "Node and call does not share enclosing callable" and
383+
result = count(DataFlowCall call, Node n | localCallNodes(call, n, _))
384+
or
385+
type = "PostUpdateNode should not equal its pre-update node" and
386+
result = count(PostUpdateNode n | postIsNotPre(n, _))
387+
or
388+
type = "PostUpdateNode should have one pre-update node" and
389+
result = count(PostUpdateNode n | postHasUniquePre(n, _))
390+
or
391+
type = "Node has multiple PostUpdateNodes" and
392+
result = count(Node n | uniquePostUpdate(n, _))
393+
or
394+
type = "PostUpdateNode does not share callable with its pre-update node" and
395+
result = count(PostUpdateNode n | postIsInSameCallable(n, _))
396+
or
397+
type = "Origin of readStep is missing a PostUpdateNode" and
398+
result = count(Node n | reverseRead(n, _))
399+
or
400+
type = "ArgumentNode is missing PostUpdateNode" and
401+
result = count(ArgumentNode n | argHasPostUpdate(n, _))
402+
or
403+
type = "PostUpdateNode should not be the target of local flow" and
404+
result = count(PostUpdateNode n | postWithInFlow(n, _))
405+
or
406+
type = "Call context too large" and
407+
result =
408+
count(DataFlowCall call, DataFlowCall ctx, DataFlowCallable callable |
409+
viableImplInCallContextTooLarge(call, ctx, callable)
410+
)
411+
or
412+
type = "Parameters with overlapping positions" and
413+
result =
414+
count(DataFlowCallable c, ParameterPosition pos, Node p |
415+
uniqueParameterNodeAtPosition(c, pos, p, _)
416+
)
417+
or
418+
type = "Parameter node with multiple positions" and
419+
result =
420+
count(DataFlowCallable c, ParameterPosition pos, Node p |
421+
uniqueParameterNodePosition(c, pos, p, _)
422+
)
423+
or
424+
type = "Non-unique content approximation" and
425+
result = count(Content c | uniqueContentApprox(c, _))
426+
or
427+
type = "Node steps to itself" and
428+
result = count(Node n | identityLocalStep(n, _))
429+
or
430+
type = "Missing call for argument node" and
431+
result = count(ArgumentNode n | missingArgumentCall(n, _))
432+
or
433+
type = "Multiple calls for argument node" and
434+
result = count(ArgumentNode arg, DataFlowCall call | multipleArgumentCall(arg, call, _))
435+
or
436+
type = "Lambda call enclosing callable mismatch" and
437+
result =
438+
count(DataFlowCall call, Node receiver | lambdaCallEnclosingCallableMismatch(call, receiver))
439+
or
440+
type = "Speculative step already hasM Model" and
441+
result = count(Node n1, Node n2 | speculativeStepAlreadyHasModel(n1, n2, _))
442+
}
340443
}

0 commit comments

Comments
 (0)