From 45690338b8cf73171b8b6eef9749bd328bda6f37 Mon Sep 17 00:00:00 2001 From: Calum Grant Date: Tue, 23 Apr 2024 13:00:01 +0100 Subject: [PATCH] Refactoring queries WIP --- .../src/experimental/refactoring/cstrings.ql | 20 +++++++++++++++ .../refactoring/fn_missing_namespace.ql | 9 +++++++ .../refactoring/fn_should_be_method.ql | 4 +++ .../refactoring/global_variables.ql | 25 +++++++++++++++++++ cpp/ql/src/experimental/refactoring/printf.ql | 7 ++++++ .../src/experimental/refactoring/relevant.qll | 6 +++++ .../refactoring/write_to_stream.ql | 25 +++++++++++++++++++ 7 files changed, 96 insertions(+) create mode 100644 cpp/ql/src/experimental/refactoring/cstrings.ql create mode 100644 cpp/ql/src/experimental/refactoring/fn_missing_namespace.ql create mode 100644 cpp/ql/src/experimental/refactoring/fn_should_be_method.ql create mode 100644 cpp/ql/src/experimental/refactoring/global_variables.ql create mode 100644 cpp/ql/src/experimental/refactoring/printf.ql create mode 100644 cpp/ql/src/experimental/refactoring/relevant.qll create mode 100644 cpp/ql/src/experimental/refactoring/write_to_stream.ql diff --git a/cpp/ql/src/experimental/refactoring/cstrings.ql b/cpp/ql/src/experimental/refactoring/cstrings.ql new file mode 100644 index 00000000000..72aee25e328 --- /dev/null +++ b/cpp/ql/src/experimental/refactoring/cstrings.ql @@ -0,0 +1,20 @@ +import cpp + +class StringVariable extends Variable { + StringVariable() { + this.getType().(PointerType).stripType().getName() = "char" + } +} + +class StringField extends StringVariable, Field +{ +} + +class StringParameter extends StringVariable, Parameter +{ +} + +from StringVariable f +where f.getFile().getRelativePath().matches("c/extractor/src/%") +and not f.getASpecifier().getName() = "extern" +select f, f.getFile().getRelativePath() diff --git a/cpp/ql/src/experimental/refactoring/fn_missing_namespace.ql b/cpp/ql/src/experimental/refactoring/fn_missing_namespace.ql new file mode 100644 index 00000000000..99b428dfde9 --- /dev/null +++ b/cpp/ql/src/experimental/refactoring/fn_missing_namespace.ql @@ -0,0 +1,9 @@ +import cpp +import relevant + +from Function fn +where + fn.getNamespace() instanceof GlobalNamespace and + not exists(fn.getDeclaringType()) and + is_relevant_result(fn.getFile()) +select fn, "This function is not declared in a namespace", fn.getFile().getRelativePath() diff --git a/cpp/ql/src/experimental/refactoring/fn_should_be_method.ql b/cpp/ql/src/experimental/refactoring/fn_should_be_method.ql new file mode 100644 index 00000000000..6c2fef4dc44 --- /dev/null +++ b/cpp/ql/src/experimental/refactoring/fn_should_be_method.ql @@ -0,0 +1,4 @@ +import cpp + +from Function fn +where not exists(fn.getDeclaringType()) and is_relevant_result(fn.getFile()) diff --git a/cpp/ql/src/experimental/refactoring/global_variables.ql b/cpp/ql/src/experimental/refactoring/global_variables.ql new file mode 100644 index 00000000000..930129688a6 --- /dev/null +++ b/cpp/ql/src/experimental/refactoring/global_variables.ql @@ -0,0 +1,25 @@ +// Flags use of global variables +import cpp + +class RelevantGlobalVariable extends GlobalVariable +{ + RelevantGlobalVariable() { + any() + } +} + +predicate is_valid_global_variable(Variable var) { + var.getType().stripType().getName() = "trie_node" or + var.getType().isConst() or + var.getType().isDeeplyConst() or + var.isConstexpr() or + var.getType() instanceof ArrayType or + var.getASpecifier().getName() = "extern" or + var.getFile().getRelativePath().matches("c/extractor/edg/%") +} + +from GlobalVariable globalVariable, string typeName +where + not is_valid_global_variable(globalVariable) and + typeName = globalVariable.getType().stripType().getName() +select globalVariable, typeName, globalVariable.getFile().getRelativePath() diff --git a/cpp/ql/src/experimental/refactoring/printf.ql b/cpp/ql/src/experimental/refactoring/printf.ql new file mode 100644 index 00000000000..15fe759deb1 --- /dev/null +++ b/cpp/ql/src/experimental/refactoring/printf.ql @@ -0,0 +1,7 @@ +import cpp +import relevant + +from Call call +where call.getTarget().getName().matches("%printf") +and is_relevant_result(call.getFile()) +select call, "Call to a printf formatter", call.getFile().getRelativePath() diff --git a/cpp/ql/src/experimental/refactoring/relevant.qll b/cpp/ql/src/experimental/refactoring/relevant.qll new file mode 100644 index 00000000000..e21203a008a --- /dev/null +++ b/cpp/ql/src/experimental/refactoring/relevant.qll @@ -0,0 +1,6 @@ +import cpp + +predicate is_relevant_result(File file) +{ + not file.getRelativePath().matches("c/extractor/edg%") +} diff --git a/cpp/ql/src/experimental/refactoring/write_to_stream.ql b/cpp/ql/src/experimental/refactoring/write_to_stream.ql new file mode 100644 index 00000000000..45082047d2c --- /dev/null +++ b/cpp/ql/src/experimental/refactoring/write_to_stream.ql @@ -0,0 +1,25 @@ +import cpp + +class ACompressedFileWrite extends Function { + ACompressedFileWrite() { + this.getName() = "operator<<" and + this.getParameter(0).getType().stripType().getName() = "a_compressed_file" + } +} + +class LabelDefinition extends Call { + LabelDefinition() { + this.getTarget() instanceof ACompressedFileWrite and + this.getArgument(1).(StringLiteral).getValue().matches("=%") + } +} + +predicate is_valid_file_write(Call call) { + call.getFile().getBaseName() = "dbscheme.cpp" +} + +from Call call +where + call.getTarget() instanceof ACompressedFileWrite + and not is_valid_file_write(call) +select call