Merge pull request #12575 from egregius313/egregius313/ql/dataflow-naming-convention-check

QL: add a check to enforce naming convention for new `DataFlow::ConfigSig` modules
This commit is contained in:
Edward Minnix III
2023-03-20 07:26:01 -04:00
committed by GitHub
4 changed files with 69 additions and 0 deletions

View File

@@ -0,0 +1,44 @@
/**
* @id ql/dataflow-module-naming-convention
* @name Data flow configuration module naming
* @description The name of a data flow configuration module should end in `Config`
* @kind problem
* @problem.severity warning
* @precision high
*/
import ql
/**
* The DataFlow configuration module signatures (`ConfigSig`, `StateConfigSig`, `FullStateConfigSig`).
*/
class ConfigSig extends TypeExpr {
ConfigSig() { this.getClassName() = ["ConfigSig", "StateConfigSig", "FullStateConfigSig"] }
}
/**
* A module that implements a data flow configuration.
*/
class DataFlowConfigModule extends Module {
DataFlowConfigModule() { this.getImplements(_) instanceof ConfigSig }
}
/**
* A file that is part of the internal dataflow library or dataflow library
* tests.
*/
class DataFlowInternalFile extends File {
DataFlowInternalFile() {
this.getRelativePath()
.matches([
"%/dataflow/internal/%", "%/dataflow/new/internal/%",
"%/ql/test/library-tests/dataflow/%"
])
}
}
from DataFlowConfigModule m
where
not m.getFile() instanceof DataFlowInternalFile and
not m.getName().matches("%Config")
select m, "Modules implementing a data flow configuration should end in `Config`."

View File

@@ -0,0 +1,2 @@
| Test.qll:11:8:11:25 | Module EmptyConfiguration | Modules implementing a data flow configuration should end in `Config`. |
| Test.qll:18:8:18:16 | Module EmptyFlow | Modules implementing a data flow configuration should end in `Config`. |

View File

@@ -0,0 +1 @@
queries/style/DataFlowConfigModuleNaming.ql

View File

@@ -0,0 +1,22 @@
import semmle.code.java.dataflow.DataFlow
// GOOD - ends with "Config"
module EmptyConfig implements DataFlow::ConfigSig {
predicate isSource(DataFlow::Node src) { none() }
predicate isSink(DataFlow::Node sink) { none() }
}
// BAD - does not end with "Config"
module EmptyConfiguration implements DataFlow::ConfigSig {
predicate isSource(DataFlow::Node src) { none() }
predicate isSink(DataFlow::Node sink) { none() }
}
// BAD - does not end with "Config"
module EmptyFlow implements DataFlow::ConfigSig {
predicate isSource(DataFlow::Node src) { none() }
predicate isSink(DataFlow::Node sink) { none() }
}