Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Shared: Add CFG consistency check for scopes with missing entry points #17585

Merged
merged 5 commits into from
Sep 26, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,19 @@ class CfgScope extends Element, @top_level_exprorstmt_parent {
CfgScope() {
this.getFile().fromSource() and
(
this instanceof Callable
this =
any(Callable c |
c.(Constructor).hasInitializer()
or
InitializerSplitting::constructorInitializes(c, _)
or
c.hasBody()
)
or
// For now, static initializer values have their own scope. Eventually, they
// should be treated like instance initializers.
this.(Assignable).(Modifiable).isStatic()
this.(Assignable).(Modifiable).isStatic() and
expr_parent_top_level_adjusted2(_, _, this)
)
}
}
Expand Down
1 change: 0 additions & 1 deletion ql/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,4 @@ target
.cache
ql/test/**/*.testproj
ql/test/**/*.actual
ql/test/**/CONSISTENCY
work
1 change: 0 additions & 1 deletion ruby/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,4 @@ extractor/target
.cache
ql/test/**/*.testproj
ql/test/**/*.actual
ql/test/**/CONSISTENCY
.codeql
14 changes: 13 additions & 1 deletion ruby/ql/consistency-queries/CfgConsistency.ql
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import codeql.ruby.controlflow.internal.ControlFlowGraphImpl::Consistency
import codeql.ruby.controlflow.internal.ControlFlowGraphImpl::Consistency as Consistency
import Consistency
import codeql.ruby.AST
import codeql.ruby.CFG
import codeql.ruby.controlflow.internal.Completion
Expand All @@ -19,3 +20,14 @@ query predicate nonPostOrderExpr(Expr e, string cls) {
c instanceof NormalCompletion
)
}

query predicate scopeNoFirst(CfgScope scope) {
Consistency::scopeNoFirst(scope) and
not scope = any(StmtSequence seq | not exists(seq.getAStmt())) and
not scope =
any(Callable c |
not exists(c.getAParameter()) and
not c.(BodyStmt).hasEnsure() and
not exists(c.(BodyStmt).getARescue())
)
}
10 changes: 9 additions & 1 deletion rust/ql/consistency-queries/CfgConsistency.ql
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import rust
import codeql.rust.controlflow.internal.ControlFlowGraphImpl::Consistency
import codeql.rust.controlflow.internal.ControlFlowGraphImpl::Consistency as Consistency
import Consistency
import codeql.rust.controlflow.ControlFlowGraph
import codeql.rust.controlflow.internal.ControlFlowGraphImpl as CfgImpl
import codeql.rust.controlflow.internal.Completion

Expand All @@ -17,3 +19,9 @@ query predicate nonPostOrderExpr(Expr e, string cls) {
c instanceof NormalCompletion
)
}

query predicate scopeNoFirst(CfgScope scope) {
Consistency::scopeNoFirst(scope) and
not scope = any(Function f | not exists(f.getBody())) and
not scope = any(ClosureExpr c | not exists(c.getBody()))
}
4 changes: 0 additions & 4 deletions rust/ql/test/library-tests/controlflow/Cfg.ql
Original file line number Diff line number Diff line change
@@ -1,7 +1,3 @@
/**
* @id rust/controlflow/cfg
*/

import rust
import codeql.rust.controlflow.ControlFlowGraph
import TestUtils
Expand Down
4 changes: 4 additions & 0 deletions shared/controlflow/codeql/controlflow/Cfg.qll
Original file line number Diff line number Diff line change
Expand Up @@ -1387,9 +1387,13 @@ module Make<LocationSig Location, InputSig<Location> Input> {
strictcount(sk.getListOrder()) > 1
}

/** Holds if `n` has multiple textual representations. */
query predicate multipleToString(Node n, string s) {
s = strictconcat(n.toString(), ",") and
strictcount(n.toString()) > 1
}

/** Holds if CFG scope `scope` lacks an initial AST node. */
query predicate scopeNoFirst(CfgScope scope) { not scopeFirst(scope, _) }
}
}
Loading