From 213047771ca2a0b4eccefb09d1d85c40bc55411d Mon Sep 17 00:00:00 2001 From: Jeroen Ketema Date: Tue, 19 Jul 2022 20:31:42 +0200 Subject: [PATCH 01/17] Upgrade `github/codeql` dependency to 2.10.5 --- c/cert/src/codeql-pack.lock.yml | 2 +- c/cert/src/qlpack.yml | 2 +- c/cert/test/codeql-pack.lock.yml | 2 +- c/common/src/codeql-pack.lock.yml | 2 +- c/common/src/qlpack.yml | 2 +- c/common/test/codeql-pack.lock.yml | 2 +- c/misra/src/codeql-pack.lock.yml | 2 +- c/misra/src/qlpack.yml | 2 +- c/misra/test/codeql-pack.lock.yml | 2 +- .../2022-06-28-detect-static-namespace-members.md | 6 ++++++ cpp/autosar/src/codeql-pack.lock.yml | 2 +- cpp/autosar/src/qlpack.yml | 2 +- cpp/autosar/test/codeql-pack.lock.yml | 2 +- ...entifierNameOfStaticFunctionReusedInNamespace.expected | 2 ++ ...rNameOfStaticNonMemberObjectReusedInNamespace.expected | 2 ++ cpp/autosar/test/rules/A2-10-4/test1b.cpp | 5 ++--- ...erObjectWithExternalOrInternalLinkageIsReused.expected | 8 ++++---- .../IdentifierNameOfAStaticFunctionIsReused.expected | 4 ++-- cpp/autosar/test/rules/A2-10-5/test1b.cpp | 3 +-- cpp/cert/src/codeql-pack.lock.yml | 2 +- cpp/cert/src/qlpack.yml | 2 +- cpp/cert/test/codeql-pack.lock.yml | 2 +- cpp/common/src/codeql-pack.lock.yml | 2 +- cpp/common/src/qlpack.yml | 2 +- cpp/common/test/codeql-pack.lock.yml | 2 +- cpp/misra/src/codeql-pack.lock.yml | 2 +- cpp/misra/src/qlpack.yml | 2 +- cpp/misra/test/codeql-pack.lock.yml | 2 +- cpp/report/src/codeql-pack.lock.yml | 2 +- cpp/report/src/qlpack.yml | 2 +- scripts/generate_modules/queries/codeql-pack.lock.yml | 2 +- scripts/generate_modules/queries/qlpack.yml | 2 +- supported_codeql_configs.json | 6 +++--- 33 files changed, 47 insertions(+), 39 deletions(-) create mode 100644 change_notes/2022-06-28-detect-static-namespace-members.md diff --git a/c/cert/src/codeql-pack.lock.yml b/c/cert/src/codeql-pack.lock.yml index b0f02a9d1f..1da7b6075b 100644 --- a/c/cert/src/codeql-pack.lock.yml +++ b/c/cert/src/codeql-pack.lock.yml @@ -1,6 +1,6 @@ --- dependencies: codeql/cpp-all: - version: 0.2.3 + version: 0.3.5 compiled: false lockVersion: 1.0.0 diff --git a/c/cert/src/qlpack.yml b/c/cert/src/qlpack.yml index fa4eeacaf1..db1a0c0e89 100644 --- a/c/cert/src/qlpack.yml +++ b/c/cert/src/qlpack.yml @@ -5,4 +5,4 @@ suites: codeql-suites license: MIT dependencies: codeql/common-c-coding-standards: '*' - codeql/cpp-all: 0.2.3 + codeql/cpp-all: 0.3.5 diff --git a/c/cert/test/codeql-pack.lock.yml b/c/cert/test/codeql-pack.lock.yml index b0f02a9d1f..1da7b6075b 100644 --- a/c/cert/test/codeql-pack.lock.yml +++ b/c/cert/test/codeql-pack.lock.yml @@ -1,6 +1,6 @@ --- dependencies: codeql/cpp-all: - version: 0.2.3 + version: 0.3.5 compiled: false lockVersion: 1.0.0 diff --git a/c/common/src/codeql-pack.lock.yml b/c/common/src/codeql-pack.lock.yml index b0f02a9d1f..1da7b6075b 100644 --- a/c/common/src/codeql-pack.lock.yml +++ b/c/common/src/codeql-pack.lock.yml @@ -1,6 +1,6 @@ --- dependencies: codeql/cpp-all: - version: 0.2.3 + version: 0.3.5 compiled: false lockVersion: 1.0.0 diff --git a/c/common/src/qlpack.yml b/c/common/src/qlpack.yml index e6f76013d7..87360ed2c3 100644 --- a/c/common/src/qlpack.yml +++ b/c/common/src/qlpack.yml @@ -3,4 +3,4 @@ version: 2.14.0-dev license: MIT dependencies: codeql/common-cpp-coding-standards: '*' - codeql/cpp-all: 0.2.3 + codeql/cpp-all: 0.3.5 diff --git a/c/common/test/codeql-pack.lock.yml b/c/common/test/codeql-pack.lock.yml index b0f02a9d1f..1da7b6075b 100644 --- a/c/common/test/codeql-pack.lock.yml +++ b/c/common/test/codeql-pack.lock.yml @@ -1,6 +1,6 @@ --- dependencies: codeql/cpp-all: - version: 0.2.3 + version: 0.3.5 compiled: false lockVersion: 1.0.0 diff --git a/c/misra/src/codeql-pack.lock.yml b/c/misra/src/codeql-pack.lock.yml index b0f02a9d1f..1da7b6075b 100644 --- a/c/misra/src/codeql-pack.lock.yml +++ b/c/misra/src/codeql-pack.lock.yml @@ -1,6 +1,6 @@ --- dependencies: codeql/cpp-all: - version: 0.2.3 + version: 0.3.5 compiled: false lockVersion: 1.0.0 diff --git a/c/misra/src/qlpack.yml b/c/misra/src/qlpack.yml index 7a3dda42cc..1da16038bc 100644 --- a/c/misra/src/qlpack.yml +++ b/c/misra/src/qlpack.yml @@ -5,4 +5,4 @@ suites: codeql-suites license: MIT dependencies: codeql/common-c-coding-standards: '*' - codeql/cpp-all: 0.2.3 + codeql/cpp-all: 0.3.5 diff --git a/c/misra/test/codeql-pack.lock.yml b/c/misra/test/codeql-pack.lock.yml index b0f02a9d1f..1da7b6075b 100644 --- a/c/misra/test/codeql-pack.lock.yml +++ b/c/misra/test/codeql-pack.lock.yml @@ -1,6 +1,6 @@ --- dependencies: codeql/cpp-all: - version: 0.2.3 + version: 0.3.5 compiled: false lockVersion: 1.0.0 diff --git a/change_notes/2022-06-28-detect-static-namespace-members.md b/change_notes/2022-06-28-detect-static-namespace-members.md new file mode 100644 index 0000000000..05af4deb79 --- /dev/null +++ b/change_notes/2022-06-28-detect-static-namespace-members.md @@ -0,0 +1,6 @@ +- `A2-10-4` - `IdentifierNameOfStaticFunctionReusedInNamespace.ql`: + - Reuse of an identifier name of a static function in a namespace is now detected. +- `A2-10-4` - `IdentifierNameOfStaticNonMemberObjectReusedInNamespace.ql`: + - Reuse of an identifier name of a static non-member object in a namespace is now detected. +- `A2-10-5` - `IdentifierNameOfStaticNonMemberObjectWithExternalOrInternalLinkageIsReused.ql`: + - Reuse of an identifier name of a static non-member object with internal linkage in a namespace is now detected. diff --git a/cpp/autosar/src/codeql-pack.lock.yml b/cpp/autosar/src/codeql-pack.lock.yml index b0f02a9d1f..1da7b6075b 100644 --- a/cpp/autosar/src/codeql-pack.lock.yml +++ b/cpp/autosar/src/codeql-pack.lock.yml @@ -1,6 +1,6 @@ --- dependencies: codeql/cpp-all: - version: 0.2.3 + version: 0.3.5 compiled: false lockVersion: 1.0.0 diff --git a/cpp/autosar/src/qlpack.yml b/cpp/autosar/src/qlpack.yml index 50dfb98efe..b866eebf80 100644 --- a/cpp/autosar/src/qlpack.yml +++ b/cpp/autosar/src/qlpack.yml @@ -5,4 +5,4 @@ suites: codeql-suites license: MIT dependencies: codeql/common-cpp-coding-standards: '*' - codeql/cpp-all: 0.2.3 + codeql/cpp-all: 0.3.5 diff --git a/cpp/autosar/test/codeql-pack.lock.yml b/cpp/autosar/test/codeql-pack.lock.yml index b0f02a9d1f..1da7b6075b 100644 --- a/cpp/autosar/test/codeql-pack.lock.yml +++ b/cpp/autosar/test/codeql-pack.lock.yml @@ -1,6 +1,6 @@ --- dependencies: codeql/cpp-all: - version: 0.2.3 + version: 0.3.5 compiled: false lockVersion: 1.0.0 diff --git a/cpp/autosar/test/rules/A2-10-4/IdentifierNameOfStaticFunctionReusedInNamespace.expected b/cpp/autosar/test/rules/A2-10-4/IdentifierNameOfStaticFunctionReusedInNamespace.expected index e69de29bb2..180e52c6f1 100644 --- a/cpp/autosar/test/rules/A2-10-4/IdentifierNameOfStaticFunctionReusedInNamespace.expected +++ b/cpp/autosar/test/rules/A2-10-4/IdentifierNameOfStaticFunctionReusedInNamespace.expected @@ -0,0 +1,2 @@ +| test1a.cpp:13:13:13:14 | f1 | Static function $@ reuses identifier of $@ | test1a.cpp:13:13:13:14 | f1 | f1 | test1b.cpp:6:13:6:14 | f1 | f1 | +| test1b.cpp:6:13:6:14 | f1 | Static function $@ reuses identifier of $@ | test1b.cpp:6:13:6:14 | f1 | f1 | test1a.cpp:13:13:13:14 | f1 | f1 | diff --git a/cpp/autosar/test/rules/A2-10-4/IdentifierNameOfStaticNonMemberObjectReusedInNamespace.expected b/cpp/autosar/test/rules/A2-10-4/IdentifierNameOfStaticNonMemberObjectReusedInNamespace.expected index e69de29bb2..9eef8da1b5 100644 --- a/cpp/autosar/test/rules/A2-10-4/IdentifierNameOfStaticNonMemberObjectReusedInNamespace.expected +++ b/cpp/autosar/test/rules/A2-10-4/IdentifierNameOfStaticNonMemberObjectReusedInNamespace.expected @@ -0,0 +1,2 @@ +| test1a.cpp:2:12:2:13 | v1 | Non-member static object $@ reuses identifier name of non-member static object $@ | test1a.cpp:2:12:2:13 | v1 | v1 | test1b.cpp:2:12:2:13 | v1 | v1 | +| test1b.cpp:2:12:2:13 | v1 | Non-member static object $@ reuses identifier name of non-member static object $@ | test1b.cpp:2:12:2:13 | v1 | v1 | test1a.cpp:2:12:2:13 | v1 | v1 | diff --git a/cpp/autosar/test/rules/A2-10-4/test1b.cpp b/cpp/autosar/test/rules/A2-10-4/test1b.cpp index 49a01226c3..c8a0e8a4b5 100644 --- a/cpp/autosar/test/rules/A2-10-4/test1b.cpp +++ b/cpp/autosar/test/rules/A2-10-4/test1b.cpp @@ -3,7 +3,6 @@ static int v1 = 3; // NON_COMPLIANT } // namespace ns1 namespace ns3 { -static void f1() {} // NON_COMPLIANT - Not accepted by Clang linker and - // therefore not alerted upon. +static void f1() {} // NON_COMPLIANT - Not accepted by Clang linker void f2() {} // COMPLIANT - Not accepted by Clang linker -} // namespace ns3 \ No newline at end of file +} // namespace ns3 diff --git a/cpp/autosar/test/rules/A2-10-5/IdentifierNameOfANonMemberObjectWithExternalOrInternalLinkageIsReused.expected b/cpp/autosar/test/rules/A2-10-5/IdentifierNameOfANonMemberObjectWithExternalOrInternalLinkageIsReused.expected index d06e645044..83409a78a2 100644 --- a/cpp/autosar/test/rules/A2-10-5/IdentifierNameOfANonMemberObjectWithExternalOrInternalLinkageIsReused.expected +++ b/cpp/autosar/test/rules/A2-10-5/IdentifierNameOfANonMemberObjectWithExternalOrInternalLinkageIsReused.expected @@ -1,4 +1,4 @@ -| test1a.cpp:6:12:6:13 | g3 | Identifier name of non-member object $@ reuses the identifier name of non-member object $@. | test1a.cpp:6:12:6:13 | g3 | g3 | test1b.cpp:7:12:7:13 | g3 | g3 | -| test1a.cpp:17:43:17:43 | number_two | Identifier name of non-member object $@ reuses the identifier name of non-member object $@. | test1a.cpp:17:43:17:43 | number_two | number_two | test1b.cpp:12:43:12:43 | number_two | number_two | -| test1b.cpp:7:12:7:13 | g3 | Identifier name of non-member object $@ reuses the identifier name of non-member object $@. | test1b.cpp:7:12:7:13 | g3 | g3 | test1a.cpp:6:12:6:13 | g3 | g3 | -| test1b.cpp:12:43:12:43 | number_two | Identifier name of non-member object $@ reuses the identifier name of non-member object $@. | test1b.cpp:12:43:12:43 | number_two | number_two | test1a.cpp:17:43:17:43 | number_two | number_two | +| test1a.cpp:2:12:2:13 | g1 | Identifier name of non-member object $@ reuses the identifier name of non-member object $@. | test1a.cpp:2:12:2:13 | g1 | g1 | test1b.cpp:2:12:2:13 | g1 | g1 | +| test1a.cpp:6:12:6:13 | g3 | Identifier name of non-member object $@ reuses the identifier name of non-member object $@. | test1a.cpp:6:12:6:13 | g3 | g3 | test1b.cpp:6:12:6:13 | g3 | g3 | +| test1b.cpp:2:12:2:13 | g1 | Identifier name of non-member object $@ reuses the identifier name of non-member object $@. | test1b.cpp:2:12:2:13 | g1 | g1 | test1a.cpp:2:12:2:13 | g1 | g1 | +| test1b.cpp:6:12:6:13 | g3 | Identifier name of non-member object $@ reuses the identifier name of non-member object $@. | test1b.cpp:6:12:6:13 | g3 | g3 | test1a.cpp:6:12:6:13 | g3 | g3 | \ No newline at end of file diff --git a/cpp/autosar/test/rules/A2-10-5/IdentifierNameOfAStaticFunctionIsReused.expected b/cpp/autosar/test/rules/A2-10-5/IdentifierNameOfAStaticFunctionIsReused.expected index d84cdee2b0..c9eea3450b 100644 --- a/cpp/autosar/test/rules/A2-10-5/IdentifierNameOfAStaticFunctionIsReused.expected +++ b/cpp/autosar/test/rules/A2-10-5/IdentifierNameOfAStaticFunctionIsReused.expected @@ -1,2 +1,2 @@ -| test1a.cpp:7:13:7:14 | f1 | Identifier name of static function $@ reuses identifier name of static function $@ | test1a.cpp:7:13:7:14 | f1 | f1 | test1b.cpp:10:13:10:14 | f1 | f1 | -| test1b.cpp:10:13:10:14 | f1 | Identifier name of static function $@ reuses identifier name of static function $@ | test1b.cpp:10:13:10:14 | f1 | f1 | test1a.cpp:7:13:7:14 | f1 | f1 | +| test1a.cpp:7:13:7:14 | f1 | Identifier name of static function $@ reuses identifier name of static function $@ | test1a.cpp:7:13:7:14 | f1 | f1 | test1b.cpp:9:13:9:14 | f1 | f1 | +| test1b.cpp:9:13:9:14 | f1 | Identifier name of static function $@ reuses identifier name of static function $@ | test1b.cpp:9:13:9:14 | f1 | f1 | test1a.cpp:7:13:7:14 | f1 | f1 | diff --git a/cpp/autosar/test/rules/A2-10-5/test1b.cpp b/cpp/autosar/test/rules/A2-10-5/test1b.cpp index f292164478..132588d5dd 100644 --- a/cpp/autosar/test/rules/A2-10-5/test1b.cpp +++ b/cpp/autosar/test/rules/A2-10-5/test1b.cpp @@ -1,6 +1,5 @@ namespace n1 { -static int g1 = 1; // NON_COMPLIANT[FALSE_NEGATIVE], considered the same as - // n1::g1 in test1a.cpp. +static int g1 = 1; // NON_COMPLIANT } namespace n2 { diff --git a/cpp/cert/src/codeql-pack.lock.yml b/cpp/cert/src/codeql-pack.lock.yml index b0f02a9d1f..1da7b6075b 100644 --- a/cpp/cert/src/codeql-pack.lock.yml +++ b/cpp/cert/src/codeql-pack.lock.yml @@ -1,6 +1,6 @@ --- dependencies: codeql/cpp-all: - version: 0.2.3 + version: 0.3.5 compiled: false lockVersion: 1.0.0 diff --git a/cpp/cert/src/qlpack.yml b/cpp/cert/src/qlpack.yml index 8be0dbd8b7..bf3b7debef 100644 --- a/cpp/cert/src/qlpack.yml +++ b/cpp/cert/src/qlpack.yml @@ -4,5 +4,5 @@ description: CERT C++ 2016 suites: codeql-suites license: MIT dependencies: - codeql/cpp-all: 0.2.3 + codeql/cpp-all: 0.3.5 codeql/common-cpp-coding-standards: '*' diff --git a/cpp/cert/test/codeql-pack.lock.yml b/cpp/cert/test/codeql-pack.lock.yml index b0f02a9d1f..1da7b6075b 100644 --- a/cpp/cert/test/codeql-pack.lock.yml +++ b/cpp/cert/test/codeql-pack.lock.yml @@ -1,6 +1,6 @@ --- dependencies: codeql/cpp-all: - version: 0.2.3 + version: 0.3.5 compiled: false lockVersion: 1.0.0 diff --git a/cpp/common/src/codeql-pack.lock.yml b/cpp/common/src/codeql-pack.lock.yml index b0f02a9d1f..1da7b6075b 100644 --- a/cpp/common/src/codeql-pack.lock.yml +++ b/cpp/common/src/codeql-pack.lock.yml @@ -1,6 +1,6 @@ --- dependencies: codeql/cpp-all: - version: 0.2.3 + version: 0.3.5 compiled: false lockVersion: 1.0.0 diff --git a/cpp/common/src/qlpack.yml b/cpp/common/src/qlpack.yml index efb4c0875f..21edb7d16c 100644 --- a/cpp/common/src/qlpack.yml +++ b/cpp/common/src/qlpack.yml @@ -2,4 +2,4 @@ name: codeql/common-cpp-coding-standards version: 2.14.0-dev license: MIT dependencies: - codeql/cpp-all: 0.2.3 + codeql/cpp-all: 0.3.5 diff --git a/cpp/common/test/codeql-pack.lock.yml b/cpp/common/test/codeql-pack.lock.yml index b0f02a9d1f..1da7b6075b 100644 --- a/cpp/common/test/codeql-pack.lock.yml +++ b/cpp/common/test/codeql-pack.lock.yml @@ -1,6 +1,6 @@ --- dependencies: codeql/cpp-all: - version: 0.2.3 + version: 0.3.5 compiled: false lockVersion: 1.0.0 diff --git a/cpp/misra/src/codeql-pack.lock.yml b/cpp/misra/src/codeql-pack.lock.yml index b0f02a9d1f..1da7b6075b 100644 --- a/cpp/misra/src/codeql-pack.lock.yml +++ b/cpp/misra/src/codeql-pack.lock.yml @@ -1,6 +1,6 @@ --- dependencies: codeql/cpp-all: - version: 0.2.3 + version: 0.3.5 compiled: false lockVersion: 1.0.0 diff --git a/cpp/misra/src/qlpack.yml b/cpp/misra/src/qlpack.yml index a6c5037b81..6d9466e54c 100644 --- a/cpp/misra/src/qlpack.yml +++ b/cpp/misra/src/qlpack.yml @@ -5,4 +5,4 @@ suites: codeql-suites license: MIT dependencies: codeql/common-cpp-coding-standards: '*' - codeql/cpp-all: 0.2.3 + codeql/cpp-all: 0.3.5 diff --git a/cpp/misra/test/codeql-pack.lock.yml b/cpp/misra/test/codeql-pack.lock.yml index b0f02a9d1f..1da7b6075b 100644 --- a/cpp/misra/test/codeql-pack.lock.yml +++ b/cpp/misra/test/codeql-pack.lock.yml @@ -1,6 +1,6 @@ --- dependencies: codeql/cpp-all: - version: 0.2.3 + version: 0.3.5 compiled: false lockVersion: 1.0.0 diff --git a/cpp/report/src/codeql-pack.lock.yml b/cpp/report/src/codeql-pack.lock.yml index b0f02a9d1f..1da7b6075b 100644 --- a/cpp/report/src/codeql-pack.lock.yml +++ b/cpp/report/src/codeql-pack.lock.yml @@ -1,6 +1,6 @@ --- dependencies: codeql/cpp-all: - version: 0.2.3 + version: 0.3.5 compiled: false lockVersion: 1.0.0 diff --git a/cpp/report/src/qlpack.yml b/cpp/report/src/qlpack.yml index 595af25c12..5b5636744d 100644 --- a/cpp/report/src/qlpack.yml +++ b/cpp/report/src/qlpack.yml @@ -2,4 +2,4 @@ name: codeql/report-cpp-coding-standards version: 2.14.0-dev license: MIT dependencies: - codeql/cpp-all: 0.2.3 + codeql/cpp-all: 0.3.5 diff --git a/scripts/generate_modules/queries/codeql-pack.lock.yml b/scripts/generate_modules/queries/codeql-pack.lock.yml index b0f02a9d1f..1da7b6075b 100644 --- a/scripts/generate_modules/queries/codeql-pack.lock.yml +++ b/scripts/generate_modules/queries/codeql-pack.lock.yml @@ -1,6 +1,6 @@ --- dependencies: codeql/cpp-all: - version: 0.2.3 + version: 0.3.5 compiled: false lockVersion: 1.0.0 diff --git a/scripts/generate_modules/queries/qlpack.yml b/scripts/generate_modules/queries/qlpack.yml index 29906305c6..76ee66f817 100644 --- a/scripts/generate_modules/queries/qlpack.yml +++ b/scripts/generate_modules/queries/qlpack.yml @@ -2,4 +2,4 @@ name: codeql/standard-library-extraction-cpp-coding-standards version: 0.0.0 license: MIT dependencies: - codeql/cpp-all: 0.2.3 + codeql/cpp-all: 0.3.5 diff --git a/supported_codeql_configs.json b/supported_codeql_configs.json index 269af480e3..b87a09bef6 100644 --- a/supported_codeql_configs.json +++ b/supported_codeql_configs.json @@ -1,9 +1,9 @@ { "supported_environment": [ { - "codeql_cli": "2.9.4", - "codeql_standard_library": "codeql-cli/v2.9.4", - "codeql_cli_bundle": "codeql-bundle-20220615" + "codeql_cli": "2.10.5", + "codeql_standard_library": "codeql-cli/v2.10.5", + "codeql_cli_bundle": "codeql-bundle-20220908" } ], "supported_language" : [ From f0dcebe76263e202698d14c1345010043e6bda11 Mon Sep 17 00:00:00 2001 From: Jeroen Ketema Date: Tue, 30 Aug 2022 14:23:07 +0200 Subject: [PATCH 02/17] Replace `XMLElement` by `XmlElement` and `XMLFile` by `XmlFile` `XMLElement` and `XMLFile` are deprecated from CodeQL 2.10.4 onwards. `XmlElement` and `XmlFile` are their direct replacements. --- .../cpp/deviations/Deviations.qll | 763 +++++++++--------- 1 file changed, 382 insertions(+), 381 deletions(-) diff --git a/cpp/common/src/codingstandards/cpp/deviations/Deviations.qll b/cpp/common/src/codingstandards/cpp/deviations/Deviations.qll index 9399607e3d..a1f69b2f51 100644 --- a/cpp/common/src/codingstandards/cpp/deviations/Deviations.qll +++ b/cpp/common/src/codingstandards/cpp/deviations/Deviations.qll @@ -4,384 +4,385 @@ * The deviation model is based on the "MISRA Compliance 2020" document. */ -import cpp -import semmle.code.cpp.XML -import codingstandards.cpp.exclusions.RuleMetadata -import codingstandards.cpp.Config - -predicate applyDeviationsAtQueryLevel() { - not exists(CodingStandardsReportDeviatedAlerts reportDeviatedResults | - // There exists at least one `report-deviated-alerts: true` command in the repository - reportDeviatedResults.getTextValue().trim() = "true" - ) -} - -/** An element which tells the analysis whether to report deviated results. */ -class CodingStandardsReportDeviatedAlerts extends XMLElement { - CodingStandardsReportDeviatedAlerts() { - getParent() instanceof CodingStandardsConfig and - hasName("report-deviated-alerts") - } -} - -/** A container of deviation records. */ -class DeviationRecords extends CodingStandardsConfigSection { - DeviationRecords() { hasName("deviations") } -} - -/** A container for the deviation permits records. */ -class DeviationPermits extends CodingStandardsConfigSection { - DeviationPermits() { hasName("deviation-permits") } -} - -/** A deviation permit record, that is specified by a permit identifier */ -class DeviationPermit extends XMLElement { - DeviationPermit() { - getParent() instanceof DeviationPermits and - hasName("deviation-permits-entry") - } - - string getRawScope() { result = getAChild("scope").getTextValue() } - - predicate hasScope() { exists(getRawScope()) } - - string getScope() { if hasScope() then result = getRawScope() else result = "" } - - string getRawJustification() { result = getAChild("justification").getTextValue() } - - predicate hasJustification() { exists(getRawJustification()) } - - string getJustification() { - if hasJustification() then result = getRawJustification() else result = "" - } - - string getRawBackground() { result = getAChild("background").getTextValue() } - - predicate hasBackground() { exists(getRawBackground()) } - - string getBackground() { if hasBackground() then result = getRawBackground() else result = "" } - - string getRawRequirements() { result = getAChild("requirements").getTextValue() } - - predicate hasRequirements() { exists(getRawRequirements()) } - - string getRequirements() { - if hasRequirements() then result = getRawRequirements() else result = "" - } - - string getRawPermitId() { result = getAChild("permit-id").getTextValue() } - - predicate hasPermitId() { exists(getRawPermitId()) } - - string getPermitId() { - // In the case of the permit identifier we do not return an empty string because that can - // result in spurious matches when an invalid permit without an id is specified, because - // the record returns an empty string for the permit id if it is not specified. - result = getRawPermitId() - } - - predicate hasCodeIdentifier() { exists(getAChild("code-identifier")) } - - /** Gets the code identifier associated with this deviation record, if any. */ - string getCodeIdentifier() { result = getAChild("code-identifier").getTextValue() } - - /** Gets the `rule-id` specified for this record, if any. */ - string getRawRuleId() { result = getAChild("rule-id").getTextValue() } - - predicate hasRuleId() { exists(getRawRuleId()) } - - string getRuleId() { if hasRuleId() then result = getRawRuleId() else result = "" } - - /** Gets the `query-id` specified for this record, if any. */ - string getRawQueryId() { result = getAChild("query-id").getTextValue() } - - predicate hasQueryId() { exists(getRawQueryId()) } - - string getQueryId() { if hasQueryId() then result = getRawQueryId() else result = "" } - - /** If the permit is invalid, get a string describing a reason for it being invalid. */ - string getAnInvalidPermitReason() { - not hasPermitId() and result = "Deviation permit does not specify a permit identifier." - or - exists(string childName | - exists(getAChild(childName)) and - not childName in [ - "permit-id", "rule-id", "query-id", "code-identifier", "scope", "justification", - "background", "requirements" - ] and - result = "Deviation permit specifies unknown property `" + childName + "`." - ) - } - - /** Holds if the deviation record is valid */ - predicate isDeviationPermitValid() { not exists(getAnInvalidPermitReason()) } -} - -/** A deviation record, that is a specified rule or query */ -class DeviationRecord extends XMLElement { - DeviationRecord() { - getParent() instanceof DeviationRecords and - hasName("deviations-entry") - } - - private string getRawScope() { result = getAChild("scope").getTextValue() } - - private string getRawJustification() { result = getAChild("justification").getTextValue() } - - private string getRawBackground() { result = getAChild("background").getTextValue() } - - private string getRawRequirements() { result = getAChild("requirements").getTextValue() } - - private string getRawPermitId() { result = getAChild("permit-id").getTextValue() } - - private XMLElement getRawRaisedBy() { result = getAChild("raised-by") } - - private string getRawRaisedByName() { result = getRawRaisedBy().getAChild("name").getTextValue() } - - private string getRawRaisedByDate() { result = getRawRaisedBy().getAChild("date").getTextValue() } - - private XMLElement getRawApprovedBy() { result = getAChild("approved-by") } - - private string getRawApprovedByName() { - result = getRawApprovedBy().getAChild("name").getTextValue() - } - - private string getRawApprovedByDate() { - result = getRawApprovedBy().getAChild("date").getTextValue() - } - - predicate hasRaisedBy() { exists(getRawRaisedBy()) } - - predicate hasApprovedBy() { exists(getRawApprovedBy()) } - - string getRaisedByName() { - if exists(getRawRaisedByName()) then result = getRawRaisedByName() else result = "" - } - - string getRaisedByDate() { - if exists(getRawRaisedByDate()) then result = getRawRaisedByDate() else result = "" - } - - string getApprovedByName() { - if exists(getRawApprovedByName()) then result = getRawApprovedByName() else result = "" - } - - string getApprovedByDate() { - if exists(getRawApprovedByDate()) then result = getRawApprovedByDate() else result = "" - } - - string getScope() { - if exists(getRawScope()) - then result = getRawScope() - else - if getADeviationPermit().hasScope() - then result = getADeviationPermit().getScope() - else result = "" - } - - string getJustification() { - if exists(getRawJustification()) - then result = getRawJustification() - else - if getADeviationPermit().hasJustification() - then result = getADeviationPermit().getJustification() - else result = "" - } - - string getBackground() { - if exists(getRawBackground()) - then result = getRawBackground() - else - if getADeviationPermit().hasBackground() - then result = getADeviationPermit().getBackground() - else result = "" - } - - string getRequirements() { - if exists(getRawRequirements()) - then result = getRawRequirements() - else - if getADeviationPermit().hasRequirements() - then result = getADeviationPermit().getRequirements() - else result = "" - } - - string getPermitId() { - if exists(getRawPermitId()) then result = getRawPermitId() else result = "" - } - - predicate hasPermitId() { exists(getRawPermitId()) } - - /** Gets the code identifier associated with this deviation record, if any. */ - string getCodeIdentifier() { - if exists(getAChild("code-identifier").getTextValue()) - then result = getAChild("code-identifier").getTextValue() - else result = getADeviationPermit().getCodeIdentifier() - } - - /** Gets a comment which starts or ends with the code identifier comment. */ - Comment getACodeIdentifierComment() { - exists(string text | - ( - result instanceof CppStyleComment and - // strip the beginning slashes - text = result.getContents().suffix(2).trim() - or - result instanceof CStyleComment and - // strip both the beginning /* and the end */ the comment - exists(string text0 | - text0 = result.getContents().suffix(2) and - text = text0.prefix(text0.length() - 2).trim() - ) and - // The /* */ comment must be a single-line comment - not text.matches("%\n%") - ) and - ( - // Code identifier appears at the start of the comment (modulo whitespace) - text.prefix(getCodeIdentifier().length()) = getCodeIdentifier() - or - // Code identifier appears at the end of the comment (modulo whitespace) - text.suffix(text.length() - getCodeIdentifier().length()) = getCodeIdentifier() - ) - ) - } - - /** Gets the `rule-id` specified for this record, if any. */ - private string getRawRuleId() { result = getAChild("rule-id").getTextValue() } - - string getRuleId() { - if exists(getRawRuleId()) - then result = getRawRuleId() - else - if exists(DeviationPermit dp | dp.getPermitId() = getPermitId() and dp.hasRuleId()) - then - exists(DeviationPermit dp | - dp.getPermitId() = getPermitId() and dp.hasRuleId() and result = dp.getRuleId() - ) - else result = "" - } - - predicate hasRuleId() { not exists(string id | id = getRuleId() and id = "") } - - /** Gets the `query-id` specified for this record, if any. */ - private string getRawQueryId() { result = getAChild("query-id").getTextValue() } - - string getQueryId() { - if exists(getRawQueryId()) - then result = getRawQueryId() - else - if getADeviationPermit().hasQueryId() - then result = getADeviationPermit().getQueryId() - else result = "" - } - - predicate hasQueryId() { not exists(string id | id = getQueryId() and id = "") } - - DeviationPermit getADeviationPermit() { - exists(DeviationPermit dp | dp.getPermitId() = getPermitId() | result = dp) - } - - predicate hasADeviationPermit() { exists(getADeviationPermit()) } - - /** If the record is invalid, get a string describing a reason for it being invalid. */ - string getAnInvalidRecordReason() { - not hasRuleId() and - not hasQueryId() and - result = "No rule-id and query-id specified for this deviation record." - or - hasRuleId() and - not exists(Query q | q.getRuleId() = getRuleId()) and - result = - "The rule-id `" + getRuleId() + "` for this deviation matches none of the available queries." - or - hasQueryId() and - not hasRuleId() and - result = - "A query-id of `" + getQueryId() + - "` is specified for this deviation, but not rule-id is specified." - or - hasRuleId() and - hasQueryId() and - not exists(Query q | q.getQueryId() = getQueryId() and q.getRuleId() = getRuleId()) and - result = - "There is no query which matches both the rule-id `" + getRuleId() + "` and the query-id `" + - getQueryId() + "`." - or - hasRaisedBy() and - not hasApprovedBy() and - result = "A deviation `raised-by` is specified without providing an `approved-by`." - or - not hasRaisedBy() and - hasApprovedBy() and - result = "A deviation `approved-by` is specified without providing a `raised-by`." - or - hasRaisedBy() and - not (exists(getRawRaisedByName()) and exists(getRawRaisedByDate())) and - result = "A deviation `raised-by` is specified without providing both a `name` and `date`." - or - hasApprovedBy() and - not (exists(getRawApprovedByName()) and exists(getRawApprovedByDate())) and - result = "A deviation `approved-by` is specified without providing both a `name` and `date`." - or - exists(DeviationPermit dp | - dp = getADeviationPermit() and - not dp.isDeviationPermitValid() and - result = "A deviation with an invalid deviation permit identified by `" + getPermitId() + "`." - ) - or - hasPermitId() and - not hasADeviationPermit() and - result = "There is no deviation permit with id `" + getPermitId() + "`." - or - exists(Query q | q.getQueryId() = getQueryId() | - not q.getEffectiveCategory().permitsDeviation() and - result = - "The deviation is applied to a query with the rule category '" + - q.getEffectiveCategory().toString() + "' that does not permit a deviation." - ) - } - - /** Holds if the deviation record is valid */ - predicate isDeviationRecordValid() { not exists(getAnInvalidRecordReason()) } - - /** - * Gets the query or queries to which this deviation record applies. - */ - Query getQuery() { - isDeviationRecordValid() and - result.getRuleId() = getRuleId() - } - - /** Gets a `Container` representing a path this record applies to, if any. */ - private Container getPathAContainer() { - not this.getFile().getParentContainer().getRelativePath() = "" and - result.getRelativePath() = - this.getFile().getParentContainer().getRelativePath() + "/" + - getAChild("paths").getAChild("paths-entry").getTextValue() - or - this.getFile().getParentContainer().getRelativePath() = "" and - result.getRelativePath() = getAChild("paths").getAChild("paths-entry").getTextValue() - } - - /** Gets a path to which this deviation applies. */ - string getADeviationPath() { - ( - if exists(getPathAContainer()) - then - // Use the path, which will be relative to this file, if specified - result = getPathAContainer().getRelativePath() - else ( - // Otherwise, if no code identifier was supplied, it applies to the parent container of the - // file itself - not exists(getCodeIdentifier()) and - result = this.getFile().getParentContainer().getRelativePath() - ) - ) - } - - cached - predicate isDeviated(Query query, string deviationPath) { - query = getQuery() and - deviationPath = getADeviationPath() - } -} + import cpp + import semmle.code.cpp.XML + import codingstandards.cpp.exclusions.RuleMetadata + import codingstandards.cpp.Config + + predicate applyDeviationsAtQueryLevel() { + not exists(CodingStandardsReportDeviatedAlerts reportDeviatedResults | + // There exists at least one `report-deviated-alerts: true` command in the repository + reportDeviatedResults.getTextValue().trim() = "true" + ) + } + + /** An element which tells the analysis whether to report deviated results. */ + class CodingStandardsReportDeviatedAlerts extends XMLElement { + CodingStandardsReportDeviatedAlerts() { + getParent() instanceof CodingStandardsConfig and + hasName("report-deviated-alerts") + } + } + + /** A container of deviation records. */ + class DeviationRecords extends CodingStandardsConfigSection { + DeviationRecords() { hasName("deviations") } + } + + /** A container for the deviation permits records. */ + class DeviationPermits extends CodingStandardsConfigSection { + DeviationPermits() { hasName("deviation-permits") } + } + + /** A deviation permit record, that is specified by a permit identifier */ + class DeviationPermit extends XMLElement { + DeviationPermit() { + getParent() instanceof DeviationPermits and + hasName("deviation-permits-entry") + } + + string getRawScope() { result = getAChild("scope").getTextValue() } + + predicate hasScope() { exists(getRawScope()) } + + string getScope() { if hasScope() then result = getRawScope() else result = "" } + + string getRawJustification() { result = getAChild("justification").getTextValue() } + + predicate hasJustification() { exists(getRawJustification()) } + + string getJustification() { + if hasJustification() then result = getRawJustification() else result = "" + } + + string getRawBackground() { result = getAChild("background").getTextValue() } + + predicate hasBackground() { exists(getRawBackground()) } + + string getBackground() { if hasBackground() then result = getRawBackground() else result = "" } + + string getRawRequirements() { result = getAChild("requirements").getTextValue() } + + predicate hasRequirements() { exists(getRawRequirements()) } + + string getRequirements() { + if hasRequirements() then result = getRawRequirements() else result = "" + } + + string getRawPermitId() { result = getAChild("permit-id").getTextValue() } + + predicate hasPermitId() { exists(getRawPermitId()) } + + string getPermitId() { + // In the case of the permit identifier we do not return an empty string because that can + // result in spurious matches when an invalid permit without an id is specified, because + // the record returns an empty string for the permit id if it is not specified. + result = getRawPermitId() + } + + predicate hasCodeIdentifier() { exists(getAChild("code-identifier")) } + + /** Gets the code identifier associated with this deviation record, if any. */ + string getCodeIdentifier() { result = getAChild("code-identifier").getTextValue() } + + /** Gets the `rule-id` specified for this record, if any. */ + string getRawRuleId() { result = getAChild("rule-id").getTextValue() } + + predicate hasRuleId() { exists(getRawRuleId()) } + + string getRuleId() { if hasRuleId() then result = getRawRuleId() else result = "" } + + /** Gets the `query-id` specified for this record, if any. */ + string getRawQueryId() { result = getAChild("query-id").getTextValue() } + + predicate hasQueryId() { exists(getRawQueryId()) } + + string getQueryId() { if hasQueryId() then result = getRawQueryId() else result = "" } + + /** If the permit is invalid, get a string describing a reason for it being invalid. */ + string getAnInvalidPermitReason() { + not hasPermitId() and result = "Deviation permit does not specify a permit identifier." + or + exists(string childName | + exists(getAChild(childName)) and + not childName in [ + "permit-id", "rule-id", "query-id", "code-identifier", "scope", "justification", + "background", "requirements" + ] and + result = "Deviation permit specifies unknown property `" + childName + "`." + ) + } + + /** Holds if the deviation record is valid */ + predicate isDeviationPermitValid() { not exists(getAnInvalidPermitReason()) } + } + + /** A deviation record, that is a specified rule or query */ + class DeviationRecord extends XMLElement { + DeviationRecord() { + getParent() instanceof DeviationRecords and + hasName("deviations-entry") + } + + private string getRawScope() { result = getAChild("scope").getTextValue() } + + private string getRawJustification() { result = getAChild("justification").getTextValue() } + + private string getRawBackground() { result = getAChild("background").getTextValue() } + + private string getRawRequirements() { result = getAChild("requirements").getTextValue() } + + private string getRawPermitId() { result = getAChild("permit-id").getTextValue() } + + private XMLElement getRawRaisedBy() { result = getAChild("raised-by") } + + private string getRawRaisedByName() { result = getRawRaisedBy().getAChild("name").getTextValue() } + + private string getRawRaisedByDate() { result = getRawRaisedBy().getAChild("date").getTextValue() } + + private XMLElement getRawApprovedBy() { result = getAChild("approved-by") } + + private string getRawApprovedByName() { + result = getRawApprovedBy().getAChild("name").getTextValue() + } + + private string getRawApprovedByDate() { + result = getRawApprovedBy().getAChild("date").getTextValue() + } + + predicate hasRaisedBy() { exists(getRawRaisedBy()) } + + predicate hasApprovedBy() { exists(getRawApprovedBy()) } + + string getRaisedByName() { + if exists(getRawRaisedByName()) then result = getRawRaisedByName() else result = "" + } + + string getRaisedByDate() { + if exists(getRawRaisedByDate()) then result = getRawRaisedByDate() else result = "" + } + + string getApprovedByName() { + if exists(getRawApprovedByName()) then result = getRawApprovedByName() else result = "" + } + + string getApprovedByDate() { + if exists(getRawApprovedByDate()) then result = getRawApprovedByDate() else result = "" + } + + string getScope() { + if exists(getRawScope()) + then result = getRawScope() + else + if getADeviationPermit().hasScope() + then result = getADeviationPermit().getScope() + else result = "" + } + + string getJustification() { + if exists(getRawJustification()) + then result = getRawJustification() + else + if getADeviationPermit().hasJustification() + then result = getADeviationPermit().getJustification() + else result = "" + } + + string getBackground() { + if exists(getRawBackground()) + then result = getRawBackground() + else + if getADeviationPermit().hasBackground() + then result = getADeviationPermit().getBackground() + else result = "" + } + + string getRequirements() { + if exists(getRawRequirements()) + then result = getRawRequirements() + else + if getADeviationPermit().hasRequirements() + then result = getADeviationPermit().getRequirements() + else result = "" + } + + string getPermitId() { + if exists(getRawPermitId()) then result = getRawPermitId() else result = "" + } + + predicate hasPermitId() { exists(getRawPermitId()) } + + /** Gets the code identifier associated with this deviation record, if any. */ + string getCodeIdentifier() { + if exists(getAChild("code-identifier").getTextValue()) + then result = getAChild("code-identifier").getTextValue() + else result = getADeviationPermit().getCodeIdentifier() + } + + /** Gets a comment which starts or ends with the code identifier comment. */ + Comment getACodeIdentifierComment() { + exists(string text | + ( + result instanceof CppStyleComment and + // strip the beginning slashes + text = result.getContents().suffix(2).trim() + or + result instanceof CStyleComment and + // strip both the beginning /* and the end */ the comment + exists(string text0 | + text0 = result.getContents().suffix(2) and + text = text0.prefix(text0.length() - 2).trim() + ) and + // The /* */ comment must be a single-line comment + not text.matches("%\n%") + ) and + ( + // Code identifier appears at the start of the comment (modulo whitespace) + text.prefix(getCodeIdentifier().length()) = getCodeIdentifier() + or + // Code identifier appears at the end of the comment (modulo whitespace) + text.suffix(text.length() - getCodeIdentifier().length()) = getCodeIdentifier() + ) + ) + } + + /** Gets the `rule-id` specified for this record, if any. */ + private string getRawRuleId() { result = getAChild("rule-id").getTextValue() } + + string getRuleId() { + if exists(getRawRuleId()) + then result = getRawRuleId() + else + if exists(DeviationPermit dp | dp.getPermitId() = getPermitId() and dp.hasRuleId()) + then + exists(DeviationPermit dp | + dp.getPermitId() = getPermitId() and dp.hasRuleId() and result = dp.getRuleId() + ) + else result = "" + } + + predicate hasRuleId() { not exists(string id | id = getRuleId() and id = "") } + + /** Gets the `query-id` specified for this record, if any. */ + private string getRawQueryId() { result = getAChild("query-id").getTextValue() } + + string getQueryId() { + if exists(getRawQueryId()) + then result = getRawQueryId() + else + if getADeviationPermit().hasQueryId() + then result = getADeviationPermit().getQueryId() + else result = "" + } + + predicate hasQueryId() { not exists(string id | id = getQueryId() and id = "") } + + DeviationPermit getADeviationPermit() { + exists(DeviationPermit dp | dp.getPermitId() = getPermitId() | result = dp) + } + + predicate hasADeviationPermit() { exists(getADeviationPermit()) } + + /** If the record is invalid, get a string describing a reason for it being invalid. */ + string getAnInvalidRecordReason() { + not hasRuleId() and + not hasQueryId() and + result = "No rule-id and query-id specified for this deviation record." + or + hasRuleId() and + not exists(Query q | q.getRuleId() = getRuleId()) and + result = + "The rule-id `" + getRuleId() + "` for this deviation matches none of the available queries." + or + hasQueryId() and + not hasRuleId() and + result = + "A query-id of `" + getQueryId() + + "` is specified for this deviation, but not rule-id is specified." + or + hasRuleId() and + hasQueryId() and + not exists(Query q | q.getQueryId() = getQueryId() and q.getRuleId() = getRuleId()) and + result = + "There is no query which matches both the rule-id `" + getRuleId() + "` and the query-id `" + + getQueryId() + "`." + or + hasRaisedBy() and + not hasApprovedBy() and + result = "A deviation `raised-by` is specified without providing an `approved-by`." + or + not hasRaisedBy() and + hasApprovedBy() and + result = "A deviation `approved-by` is specified without providing a `raised-by`." + or + hasRaisedBy() and + not (exists(getRawRaisedByName()) and exists(getRawRaisedByDate())) and + result = "A deviation `raised-by` is specified without providing both a `name` and `date`." + or + hasApprovedBy() and + not (exists(getRawApprovedByName()) and exists(getRawApprovedByDate())) and + result = "A deviation `approved-by` is specified without providing both a `name` and `date`." + or + exists(DeviationPermit dp | + dp = getADeviationPermit() and + not dp.isDeviationPermitValid() and + result = "A deviation with an invalid deviation permit identified by `" + getPermitId() + "`." + ) + or + hasPermitId() and + not hasADeviationPermit() and + result = "There is no deviation permit with id `" + getPermitId() + "`." + or + exists(Query q | q.getQueryId() = getQueryId() | + not q.getEffectiveCategory().permitsDeviation() and + result = + "The deviation is applied to a query with the rule category '" + + q.getEffectiveCategory().toString() + "' that does not permit a deviation." + ) + } + + /** Holds if the deviation record is valid */ + predicate isDeviationRecordValid() { not exists(getAnInvalidRecordReason()) } + + /** + * Gets the query or queries to which this deviation record applies. + */ + Query getQuery() { + isDeviationRecordValid() and + result.getRuleId() = getRuleId() + } + + /** Gets a `Container` representing a path this record applies to, if any. */ + private Container getPathAContainer() { + not this.getFile().getParentContainer().getRelativePath() = "" and + result.getRelativePath() = + this.getFile().getParentContainer().getRelativePath() + "/" + + getAChild("paths").getAChild("paths-entry").getTextValue() + or + this.getFile().getParentContainer().getRelativePath() = "" and + result.getRelativePath() = getAChild("paths").getAChild("paths-entry").getTextValue() + } + + /** Gets a path to which this deviation applies. */ + string getADeviationPath() { + ( + if exists(getPathAContainer()) + then + // Use the path, which will be relative to this file, if specified + result = getPathAContainer().getRelativePath() + else ( + // Otherwise, if no code identifier was supplied, it applies to the parent container of the + // file itself + not exists(getCodeIdentifier()) and + result = this.getFile().getParentContainer().getRelativePath() + ) + ) + } + + cached + predicate isDeviated(Query query, string deviationPath) { + query = getQuery() and + deviationPath = getADeviationPath() + } + } + \ No newline at end of file From 178eddc4d4aad682bb9c87a1733c02902925315e Mon Sep 17 00:00:00 2001 From: Jeroen Ketema Date: Tue, 19 Jul 2022 20:31:42 +0200 Subject: [PATCH 03/17] Fix A2-10-4 and A2-10-5 test results --- cpp/common/src/codingstandards/cpp/Config.qll | 6 +++--- .../src/codingstandards/cpp/deviations/Deviations.qll | 10 +++++----- .../GuidelineRecategorizations.qll | 2 +- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/cpp/common/src/codingstandards/cpp/Config.qll b/cpp/common/src/codingstandards/cpp/Config.qll index 7d12340719..5ce3f7a035 100644 --- a/cpp/common/src/codingstandards/cpp/Config.qll +++ b/cpp/common/src/codingstandards/cpp/Config.qll @@ -8,7 +8,7 @@ import codingstandards.cpp.exclusions.RuleMetadata import codingstandards.cpp.deviations.Deviations /** A `coding-standards.xml` configuration file (usually generated from an YAML configuration file). */ -class CodingStandardsFile extends XMLFile { +class CodingStandardsFile extends XmlFile { CodingStandardsFile() { this.getBaseName() = "coding-standards.xml" and // Must be within the users source code. @@ -16,12 +16,12 @@ class CodingStandardsFile extends XMLFile { } } -class CodingStandardsConfigSection extends XMLElement { +class CodingStandardsConfigSection extends XmlElement { CodingStandardsConfigSection() { getParent() instanceof CodingStandardsConfig } } /** A "Coding Standards" configuration file */ -class CodingStandardsConfig extends XMLElement { +class CodingStandardsConfig extends XmlElement { CodingStandardsConfig() { any(CodingStandardsFile csf).getARootElement() = this and this.getName() = "codingstandards" diff --git a/cpp/common/src/codingstandards/cpp/deviations/Deviations.qll b/cpp/common/src/codingstandards/cpp/deviations/Deviations.qll index a1f69b2f51..d85d6a015b 100644 --- a/cpp/common/src/codingstandards/cpp/deviations/Deviations.qll +++ b/cpp/common/src/codingstandards/cpp/deviations/Deviations.qll @@ -17,7 +17,7 @@ } /** An element which tells the analysis whether to report deviated results. */ - class CodingStandardsReportDeviatedAlerts extends XMLElement { + class CodingStandardsReportDeviatedAlerts extends XmlElement { CodingStandardsReportDeviatedAlerts() { getParent() instanceof CodingStandardsConfig and hasName("report-deviated-alerts") @@ -35,7 +35,7 @@ } /** A deviation permit record, that is specified by a permit identifier */ - class DeviationPermit extends XMLElement { + class DeviationPermit extends XmlElement { DeviationPermit() { getParent() instanceof DeviationPermits and hasName("deviation-permits-entry") @@ -118,7 +118,7 @@ } /** A deviation record, that is a specified rule or query */ - class DeviationRecord extends XMLElement { + class DeviationRecord extends XmlElement { DeviationRecord() { getParent() instanceof DeviationRecords and hasName("deviations-entry") @@ -134,13 +134,13 @@ private string getRawPermitId() { result = getAChild("permit-id").getTextValue() } - private XMLElement getRawRaisedBy() { result = getAChild("raised-by") } + private XmlElement getRawRaisedBy() { result = getAChild("raised-by") } private string getRawRaisedByName() { result = getRawRaisedBy().getAChild("name").getTextValue() } private string getRawRaisedByDate() { result = getRawRaisedBy().getAChild("date").getTextValue() } - private XMLElement getRawApprovedBy() { result = getAChild("approved-by") } + private XmlElement getRawApprovedBy() { result = getAChild("approved-by") } private string getRawApprovedByName() { result = getRawApprovedBy().getAChild("name").getTextValue() diff --git a/cpp/common/src/codingstandards/cpp/guideline_recategorizations/GuidelineRecategorizations.qll b/cpp/common/src/codingstandards/cpp/guideline_recategorizations/GuidelineRecategorizations.qll index ff148a4a72..ec5731f1bf 100644 --- a/cpp/common/src/codingstandards/cpp/guideline_recategorizations/GuidelineRecategorizations.qll +++ b/cpp/common/src/codingstandards/cpp/guideline_recategorizations/GuidelineRecategorizations.qll @@ -12,7 +12,7 @@ class GuidelineRecategorizations extends CodingStandardsConfigSection { GuidelineRecategorizations() { hasName("guideline-recategorizations") } } -class GuidelineRecategorization extends XMLElement { +class GuidelineRecategorization extends XmlElement { GuidelineRecategorization() { getParent() instanceof GuidelineRecategorizations and hasName("guideline-recategorizations-entry") From 834402729e356521f3342cb272dbdc65bef47f54 Mon Sep 17 00:00:00 2001 From: Mauro Baluda Date: Fri, 3 Mar 2023 11:08:19 +0100 Subject: [PATCH 04/17] Update supported_codeql_configs.json --- supported_codeql_configs.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/supported_codeql_configs.json b/supported_codeql_configs.json index b87a09bef6..c6c35979d9 100644 --- a/supported_codeql_configs.json +++ b/supported_codeql_configs.json @@ -14,4 +14,4 @@ "language" : "c" } ] -} \ No newline at end of file +} From 1cdf4d86b5db862a63b93d709985dda4b5b22cdb Mon Sep 17 00:00:00 2001 From: Mauro Baluda Date: Fri, 3 Mar 2023 11:13:29 +0100 Subject: [PATCH 05/17] Update Deviations.qll --- .../cpp/deviations/Deviations.qll | 763 +++++++++--------- 1 file changed, 381 insertions(+), 382 deletions(-) diff --git a/cpp/common/src/codingstandards/cpp/deviations/Deviations.qll b/cpp/common/src/codingstandards/cpp/deviations/Deviations.qll index d85d6a015b..4dfadd12eb 100644 --- a/cpp/common/src/codingstandards/cpp/deviations/Deviations.qll +++ b/cpp/common/src/codingstandards/cpp/deviations/Deviations.qll @@ -4,385 +4,384 @@ * The deviation model is based on the "MISRA Compliance 2020" document. */ - import cpp - import semmle.code.cpp.XML - import codingstandards.cpp.exclusions.RuleMetadata - import codingstandards.cpp.Config - - predicate applyDeviationsAtQueryLevel() { - not exists(CodingStandardsReportDeviatedAlerts reportDeviatedResults | - // There exists at least one `report-deviated-alerts: true` command in the repository - reportDeviatedResults.getTextValue().trim() = "true" - ) - } - - /** An element which tells the analysis whether to report deviated results. */ - class CodingStandardsReportDeviatedAlerts extends XmlElement { - CodingStandardsReportDeviatedAlerts() { - getParent() instanceof CodingStandardsConfig and - hasName("report-deviated-alerts") - } - } - - /** A container of deviation records. */ - class DeviationRecords extends CodingStandardsConfigSection { - DeviationRecords() { hasName("deviations") } - } - - /** A container for the deviation permits records. */ - class DeviationPermits extends CodingStandardsConfigSection { - DeviationPermits() { hasName("deviation-permits") } - } - - /** A deviation permit record, that is specified by a permit identifier */ - class DeviationPermit extends XmlElement { - DeviationPermit() { - getParent() instanceof DeviationPermits and - hasName("deviation-permits-entry") - } - - string getRawScope() { result = getAChild("scope").getTextValue() } - - predicate hasScope() { exists(getRawScope()) } - - string getScope() { if hasScope() then result = getRawScope() else result = "" } - - string getRawJustification() { result = getAChild("justification").getTextValue() } - - predicate hasJustification() { exists(getRawJustification()) } - - string getJustification() { - if hasJustification() then result = getRawJustification() else result = "" - } - - string getRawBackground() { result = getAChild("background").getTextValue() } - - predicate hasBackground() { exists(getRawBackground()) } - - string getBackground() { if hasBackground() then result = getRawBackground() else result = "" } - - string getRawRequirements() { result = getAChild("requirements").getTextValue() } - - predicate hasRequirements() { exists(getRawRequirements()) } - - string getRequirements() { - if hasRequirements() then result = getRawRequirements() else result = "" - } - - string getRawPermitId() { result = getAChild("permit-id").getTextValue() } - - predicate hasPermitId() { exists(getRawPermitId()) } - - string getPermitId() { - // In the case of the permit identifier we do not return an empty string because that can - // result in spurious matches when an invalid permit without an id is specified, because - // the record returns an empty string for the permit id if it is not specified. - result = getRawPermitId() - } - - predicate hasCodeIdentifier() { exists(getAChild("code-identifier")) } - - /** Gets the code identifier associated with this deviation record, if any. */ - string getCodeIdentifier() { result = getAChild("code-identifier").getTextValue() } - - /** Gets the `rule-id` specified for this record, if any. */ - string getRawRuleId() { result = getAChild("rule-id").getTextValue() } - - predicate hasRuleId() { exists(getRawRuleId()) } - - string getRuleId() { if hasRuleId() then result = getRawRuleId() else result = "" } - - /** Gets the `query-id` specified for this record, if any. */ - string getRawQueryId() { result = getAChild("query-id").getTextValue() } - - predicate hasQueryId() { exists(getRawQueryId()) } - - string getQueryId() { if hasQueryId() then result = getRawQueryId() else result = "" } - - /** If the permit is invalid, get a string describing a reason for it being invalid. */ - string getAnInvalidPermitReason() { - not hasPermitId() and result = "Deviation permit does not specify a permit identifier." - or - exists(string childName | - exists(getAChild(childName)) and - not childName in [ - "permit-id", "rule-id", "query-id", "code-identifier", "scope", "justification", - "background", "requirements" - ] and - result = "Deviation permit specifies unknown property `" + childName + "`." - ) - } - - /** Holds if the deviation record is valid */ - predicate isDeviationPermitValid() { not exists(getAnInvalidPermitReason()) } - } - - /** A deviation record, that is a specified rule or query */ - class DeviationRecord extends XmlElement { - DeviationRecord() { - getParent() instanceof DeviationRecords and - hasName("deviations-entry") - } - - private string getRawScope() { result = getAChild("scope").getTextValue() } - - private string getRawJustification() { result = getAChild("justification").getTextValue() } - - private string getRawBackground() { result = getAChild("background").getTextValue() } - - private string getRawRequirements() { result = getAChild("requirements").getTextValue() } - - private string getRawPermitId() { result = getAChild("permit-id").getTextValue() } - - private XmlElement getRawRaisedBy() { result = getAChild("raised-by") } - - private string getRawRaisedByName() { result = getRawRaisedBy().getAChild("name").getTextValue() } - - private string getRawRaisedByDate() { result = getRawRaisedBy().getAChild("date").getTextValue() } - - private XmlElement getRawApprovedBy() { result = getAChild("approved-by") } - - private string getRawApprovedByName() { - result = getRawApprovedBy().getAChild("name").getTextValue() - } - - private string getRawApprovedByDate() { - result = getRawApprovedBy().getAChild("date").getTextValue() - } - - predicate hasRaisedBy() { exists(getRawRaisedBy()) } - - predicate hasApprovedBy() { exists(getRawApprovedBy()) } - - string getRaisedByName() { - if exists(getRawRaisedByName()) then result = getRawRaisedByName() else result = "" - } - - string getRaisedByDate() { - if exists(getRawRaisedByDate()) then result = getRawRaisedByDate() else result = "" - } - - string getApprovedByName() { - if exists(getRawApprovedByName()) then result = getRawApprovedByName() else result = "" - } - - string getApprovedByDate() { - if exists(getRawApprovedByDate()) then result = getRawApprovedByDate() else result = "" - } - - string getScope() { - if exists(getRawScope()) - then result = getRawScope() - else - if getADeviationPermit().hasScope() - then result = getADeviationPermit().getScope() - else result = "" - } - - string getJustification() { - if exists(getRawJustification()) - then result = getRawJustification() - else - if getADeviationPermit().hasJustification() - then result = getADeviationPermit().getJustification() - else result = "" - } - - string getBackground() { - if exists(getRawBackground()) - then result = getRawBackground() - else - if getADeviationPermit().hasBackground() - then result = getADeviationPermit().getBackground() - else result = "" - } - - string getRequirements() { - if exists(getRawRequirements()) - then result = getRawRequirements() - else - if getADeviationPermit().hasRequirements() - then result = getADeviationPermit().getRequirements() - else result = "" - } - - string getPermitId() { - if exists(getRawPermitId()) then result = getRawPermitId() else result = "" - } - - predicate hasPermitId() { exists(getRawPermitId()) } - - /** Gets the code identifier associated with this deviation record, if any. */ - string getCodeIdentifier() { - if exists(getAChild("code-identifier").getTextValue()) - then result = getAChild("code-identifier").getTextValue() - else result = getADeviationPermit().getCodeIdentifier() - } - - /** Gets a comment which starts or ends with the code identifier comment. */ - Comment getACodeIdentifierComment() { - exists(string text | - ( - result instanceof CppStyleComment and - // strip the beginning slashes - text = result.getContents().suffix(2).trim() - or - result instanceof CStyleComment and - // strip both the beginning /* and the end */ the comment - exists(string text0 | - text0 = result.getContents().suffix(2) and - text = text0.prefix(text0.length() - 2).trim() - ) and - // The /* */ comment must be a single-line comment - not text.matches("%\n%") - ) and - ( - // Code identifier appears at the start of the comment (modulo whitespace) - text.prefix(getCodeIdentifier().length()) = getCodeIdentifier() - or - // Code identifier appears at the end of the comment (modulo whitespace) - text.suffix(text.length() - getCodeIdentifier().length()) = getCodeIdentifier() - ) - ) - } - - /** Gets the `rule-id` specified for this record, if any. */ - private string getRawRuleId() { result = getAChild("rule-id").getTextValue() } - - string getRuleId() { - if exists(getRawRuleId()) - then result = getRawRuleId() - else - if exists(DeviationPermit dp | dp.getPermitId() = getPermitId() and dp.hasRuleId()) - then - exists(DeviationPermit dp | - dp.getPermitId() = getPermitId() and dp.hasRuleId() and result = dp.getRuleId() - ) - else result = "" - } - - predicate hasRuleId() { not exists(string id | id = getRuleId() and id = "") } - - /** Gets the `query-id` specified for this record, if any. */ - private string getRawQueryId() { result = getAChild("query-id").getTextValue() } - - string getQueryId() { - if exists(getRawQueryId()) - then result = getRawQueryId() - else - if getADeviationPermit().hasQueryId() - then result = getADeviationPermit().getQueryId() - else result = "" - } - - predicate hasQueryId() { not exists(string id | id = getQueryId() and id = "") } - - DeviationPermit getADeviationPermit() { - exists(DeviationPermit dp | dp.getPermitId() = getPermitId() | result = dp) - } - - predicate hasADeviationPermit() { exists(getADeviationPermit()) } - - /** If the record is invalid, get a string describing a reason for it being invalid. */ - string getAnInvalidRecordReason() { - not hasRuleId() and - not hasQueryId() and - result = "No rule-id and query-id specified for this deviation record." - or - hasRuleId() and - not exists(Query q | q.getRuleId() = getRuleId()) and - result = - "The rule-id `" + getRuleId() + "` for this deviation matches none of the available queries." - or - hasQueryId() and - not hasRuleId() and - result = - "A query-id of `" + getQueryId() + - "` is specified for this deviation, but not rule-id is specified." - or - hasRuleId() and - hasQueryId() and - not exists(Query q | q.getQueryId() = getQueryId() and q.getRuleId() = getRuleId()) and - result = - "There is no query which matches both the rule-id `" + getRuleId() + "` and the query-id `" + - getQueryId() + "`." - or - hasRaisedBy() and - not hasApprovedBy() and - result = "A deviation `raised-by` is specified without providing an `approved-by`." - or - not hasRaisedBy() and - hasApprovedBy() and - result = "A deviation `approved-by` is specified without providing a `raised-by`." - or - hasRaisedBy() and - not (exists(getRawRaisedByName()) and exists(getRawRaisedByDate())) and - result = "A deviation `raised-by` is specified without providing both a `name` and `date`." - or - hasApprovedBy() and - not (exists(getRawApprovedByName()) and exists(getRawApprovedByDate())) and - result = "A deviation `approved-by` is specified without providing both a `name` and `date`." - or - exists(DeviationPermit dp | - dp = getADeviationPermit() and - not dp.isDeviationPermitValid() and - result = "A deviation with an invalid deviation permit identified by `" + getPermitId() + "`." - ) - or - hasPermitId() and - not hasADeviationPermit() and - result = "There is no deviation permit with id `" + getPermitId() + "`." - or - exists(Query q | q.getQueryId() = getQueryId() | - not q.getEffectiveCategory().permitsDeviation() and - result = - "The deviation is applied to a query with the rule category '" + - q.getEffectiveCategory().toString() + "' that does not permit a deviation." - ) - } - - /** Holds if the deviation record is valid */ - predicate isDeviationRecordValid() { not exists(getAnInvalidRecordReason()) } - - /** - * Gets the query or queries to which this deviation record applies. - */ - Query getQuery() { - isDeviationRecordValid() and - result.getRuleId() = getRuleId() - } - - /** Gets a `Container` representing a path this record applies to, if any. */ - private Container getPathAContainer() { - not this.getFile().getParentContainer().getRelativePath() = "" and - result.getRelativePath() = - this.getFile().getParentContainer().getRelativePath() + "/" + - getAChild("paths").getAChild("paths-entry").getTextValue() - or - this.getFile().getParentContainer().getRelativePath() = "" and - result.getRelativePath() = getAChild("paths").getAChild("paths-entry").getTextValue() - } - - /** Gets a path to which this deviation applies. */ - string getADeviationPath() { - ( - if exists(getPathAContainer()) - then - // Use the path, which will be relative to this file, if specified - result = getPathAContainer().getRelativePath() - else ( - // Otherwise, if no code identifier was supplied, it applies to the parent container of the - // file itself - not exists(getCodeIdentifier()) and - result = this.getFile().getParentContainer().getRelativePath() - ) - ) - } - - cached - predicate isDeviated(Query query, string deviationPath) { - query = getQuery() and - deviationPath = getADeviationPath() - } - } - \ No newline at end of file +import cpp +import semmle.code.cpp.XML +import codingstandards.cpp.exclusions.RuleMetadata +import codingstandards.cpp.Config + +predicate applyDeviationsAtQueryLevel() { + not exists(CodingStandardsReportDeviatedAlerts reportDeviatedResults | + // There exists at least one `report-deviated-alerts: true` command in the repository + reportDeviatedResults.getTextValue().trim() = "true" + ) +} + +/** An element which tells the analysis whether to report deviated results. */ +class CodingStandardsReportDeviatedAlerts extends XmlElement { + CodingStandardsReportDeviatedAlerts() { + getParent() instanceof CodingStandardsConfig and + hasName("report-deviated-alerts") + } +} + +/** A container of deviation records. */ +class DeviationRecords extends CodingStandardsConfigSection { + DeviationRecords() { hasName("deviations") } +} + +/** A container for the deviation permits records. */ +class DeviationPermits extends CodingStandardsConfigSection { + DeviationPermits() { hasName("deviation-permits") } +} + +/** A deviation permit record, that is specified by a permit identifier */ +class DeviationPermit extends XmlElement { + DeviationPermit() { + getParent() instanceof DeviationPermits and + hasName("deviation-permits-entry") + } + + string getRawScope() { result = getAChild("scope").getTextValue() } + + predicate hasScope() { exists(getRawScope()) } + + string getScope() { if hasScope() then result = getRawScope() else result = "" } + + string getRawJustification() { result = getAChild("justification").getTextValue() } + + predicate hasJustification() { exists(getRawJustification()) } + + string getJustification() { + if hasJustification() then result = getRawJustification() else result = "" + } + + string getRawBackground() { result = getAChild("background").getTextValue() } + + predicate hasBackground() { exists(getRawBackground()) } + + string getBackground() { if hasBackground() then result = getRawBackground() else result = "" } + + string getRawRequirements() { result = getAChild("requirements").getTextValue() } + + predicate hasRequirements() { exists(getRawRequirements()) } + + string getRequirements() { + if hasRequirements() then result = getRawRequirements() else result = "" + } + + string getRawPermitId() { result = getAChild("permit-id").getTextValue() } + + predicate hasPermitId() { exists(getRawPermitId()) } + + string getPermitId() { + // In the case of the permit identifier we do not return an empty string because that can + // result in spurious matches when an invalid permit without an id is specified, because + // the record returns an empty string for the permit id if it is not specified. + result = getRawPermitId() + } + + predicate hasCodeIdentifier() { exists(getAChild("code-identifier")) } + + /** Gets the code identifier associated with this deviation record, if any. */ + string getCodeIdentifier() { result = getAChild("code-identifier").getTextValue() } + + /** Gets the `rule-id` specified for this record, if any. */ + string getRawRuleId() { result = getAChild("rule-id").getTextValue() } + + predicate hasRuleId() { exists(getRawRuleId()) } + + string getRuleId() { if hasRuleId() then result = getRawRuleId() else result = "" } + + /** Gets the `query-id` specified for this record, if any. */ + string getRawQueryId() { result = getAChild("query-id").getTextValue() } + + predicate hasQueryId() { exists(getRawQueryId()) } + + string getQueryId() { if hasQueryId() then result = getRawQueryId() else result = "" } + + /** If the permit is invalid, get a string describing a reason for it being invalid. */ + string getAnInvalidPermitReason() { + not hasPermitId() and result = "Deviation permit does not specify a permit identifier." + or + exists(string childName | + exists(getAChild(childName)) and + not childName in [ + "permit-id", "rule-id", "query-id", "code-identifier", "scope", "justification", + "background", "requirements" + ] and + result = "Deviation permit specifies unknown property `" + childName + "`." + ) + } + + /** Holds if the deviation record is valid */ + predicate isDeviationPermitValid() { not exists(getAnInvalidPermitReason()) } +} + +/** A deviation record, that is a specified rule or query */ +class DeviationRecord extends XmlElement { + DeviationRecord() { + getParent() instanceof DeviationRecords and + hasName("deviations-entry") + } + + private string getRawScope() { result = getAChild("scope").getTextValue() } + + private string getRawJustification() { result = getAChild("justification").getTextValue() } + + private string getRawBackground() { result = getAChild("background").getTextValue() } + + private string getRawRequirements() { result = getAChild("requirements").getTextValue() } + + private string getRawPermitId() { result = getAChild("permit-id").getTextValue() } + + private XmlElement getRawRaisedBy() { result = getAChild("raised-by") } + + private string getRawRaisedByName() { result = getRawRaisedBy().getAChild("name").getTextValue() } + + private string getRawRaisedByDate() { result = getRawRaisedBy().getAChild("date").getTextValue() } + + private XmlElement getRawApprovedBy() { result = getAChild("approved-by") } + + private string getRawApprovedByName() { + result = getRawApprovedBy().getAChild("name").getTextValue() + } + + private string getRawApprovedByDate() { + result = getRawApprovedBy().getAChild("date").getTextValue() + } + + predicate hasRaisedBy() { exists(getRawRaisedBy()) } + + predicate hasApprovedBy() { exists(getRawApprovedBy()) } + + string getRaisedByName() { + if exists(getRawRaisedByName()) then result = getRawRaisedByName() else result = "" + } + + string getRaisedByDate() { + if exists(getRawRaisedByDate()) then result = getRawRaisedByDate() else result = "" + } + + string getApprovedByName() { + if exists(getRawApprovedByName()) then result = getRawApprovedByName() else result = "" + } + + string getApprovedByDate() { + if exists(getRawApprovedByDate()) then result = getRawApprovedByDate() else result = "" + } + + string getScope() { + if exists(getRawScope()) + then result = getRawScope() + else + if getADeviationPermit().hasScope() + then result = getADeviationPermit().getScope() + else result = "" + } + + string getJustification() { + if exists(getRawJustification()) + then result = getRawJustification() + else + if getADeviationPermit().hasJustification() + then result = getADeviationPermit().getJustification() + else result = "" + } + + string getBackground() { + if exists(getRawBackground()) + then result = getRawBackground() + else + if getADeviationPermit().hasBackground() + then result = getADeviationPermit().getBackground() + else result = "" + } + + string getRequirements() { + if exists(getRawRequirements()) + then result = getRawRequirements() + else + if getADeviationPermit().hasRequirements() + then result = getADeviationPermit().getRequirements() + else result = "" + } + + string getPermitId() { + if exists(getRawPermitId()) then result = getRawPermitId() else result = "" + } + + predicate hasPermitId() { exists(getRawPermitId()) } + + /** Gets the code identifier associated with this deviation record, if any. */ + string getCodeIdentifier() { + if exists(getAChild("code-identifier").getTextValue()) + then result = getAChild("code-identifier").getTextValue() + else result = getADeviationPermit().getCodeIdentifier() + } + + /** Gets a comment which starts or ends with the code identifier comment. */ + Comment getACodeIdentifierComment() { + exists(string text | + ( + result instanceof CppStyleComment and + // strip the beginning slashes + text = result.getContents().suffix(2).trim() + or + result instanceof CStyleComment and + // strip both the beginning /* and the end */ the comment + exists(string text0 | + text0 = result.getContents().suffix(2) and + text = text0.prefix(text0.length() - 2).trim() + ) and + // The /* */ comment must be a single-line comment + not text.matches("%\n%") + ) and + ( + // Code identifier appears at the start of the comment (modulo whitespace) + text.prefix(getCodeIdentifier().length()) = getCodeIdentifier() + or + // Code identifier appears at the end of the comment (modulo whitespace) + text.suffix(text.length() - getCodeIdentifier().length()) = getCodeIdentifier() + ) + ) + } + + /** Gets the `rule-id` specified for this record, if any. */ + private string getRawRuleId() { result = getAChild("rule-id").getTextValue() } + + string getRuleId() { + if exists(getRawRuleId()) + then result = getRawRuleId() + else + if exists(DeviationPermit dp | dp.getPermitId() = getPermitId() and dp.hasRuleId()) + then + exists(DeviationPermit dp | + dp.getPermitId() = getPermitId() and dp.hasRuleId() and result = dp.getRuleId() + ) + else result = "" + } + + predicate hasRuleId() { not exists(string id | id = getRuleId() and id = "") } + + /** Gets the `query-id` specified for this record, if any. */ + private string getRawQueryId() { result = getAChild("query-id").getTextValue() } + + string getQueryId() { + if exists(getRawQueryId()) + then result = getRawQueryId() + else + if getADeviationPermit().hasQueryId() + then result = getADeviationPermit().getQueryId() + else result = "" + } + + predicate hasQueryId() { not exists(string id | id = getQueryId() and id = "") } + + DeviationPermit getADeviationPermit() { + exists(DeviationPermit dp | dp.getPermitId() = getPermitId() | result = dp) + } + + predicate hasADeviationPermit() { exists(getADeviationPermit()) } + + /** If the record is invalid, get a string describing a reason for it being invalid. */ + string getAnInvalidRecordReason() { + not hasRuleId() and + not hasQueryId() and + result = "No rule-id and query-id specified for this deviation record." + or + hasRuleId() and + not exists(Query q | q.getRuleId() = getRuleId()) and + result = + "The rule-id `" + getRuleId() + "` for this deviation matches none of the available queries." + or + hasQueryId() and + not hasRuleId() and + result = + "A query-id of `" + getQueryId() + + "` is specified for this deviation, but not rule-id is specified." + or + hasRuleId() and + hasQueryId() and + not exists(Query q | q.getQueryId() = getQueryId() and q.getRuleId() = getRuleId()) and + result = + "There is no query which matches both the rule-id `" + getRuleId() + "` and the query-id `" + + getQueryId() + "`." + or + hasRaisedBy() and + not hasApprovedBy() and + result = "A deviation `raised-by` is specified without providing an `approved-by`." + or + not hasRaisedBy() and + hasApprovedBy() and + result = "A deviation `approved-by` is specified without providing a `raised-by`." + or + hasRaisedBy() and + not (exists(getRawRaisedByName()) and exists(getRawRaisedByDate())) and + result = "A deviation `raised-by` is specified without providing both a `name` and `date`." + or + hasApprovedBy() and + not (exists(getRawApprovedByName()) and exists(getRawApprovedByDate())) and + result = "A deviation `approved-by` is specified without providing both a `name` and `date`." + or + exists(DeviationPermit dp | + dp = getADeviationPermit() and + not dp.isDeviationPermitValid() and + result = "A deviation with an invalid deviation permit identified by `" + getPermitId() + "`." + ) + or + hasPermitId() and + not hasADeviationPermit() and + result = "There is no deviation permit with id `" + getPermitId() + "`." + or + exists(Query q | q.getQueryId() = getQueryId() | + not q.getEffectiveCategory().permitsDeviation() and + result = + "The deviation is applied to a query with the rule category '" + + q.getEffectiveCategory().toString() + "' that does not permit a deviation." + ) + } + + /** Holds if the deviation record is valid */ + predicate isDeviationRecordValid() { not exists(getAnInvalidRecordReason()) } + + /** + * Gets the query or queries to which this deviation record applies. + */ + Query getQuery() { + isDeviationRecordValid() and + result.getRuleId() = getRuleId() + } + + /** Gets a `Container` representing a path this record applies to, if any. */ + private Container getPathAContainer() { + not this.getFile().getParentContainer().getRelativePath() = "" and + result.getRelativePath() = + this.getFile().getParentContainer().getRelativePath() + "/" + + getAChild("paths").getAChild("paths-entry").getTextValue() + or + this.getFile().getParentContainer().getRelativePath() = "" and + result.getRelativePath() = getAChild("paths").getAChild("paths-entry").getTextValue() + } + + /** Gets a path to which this deviation applies. */ + string getADeviationPath() { + ( + if exists(getPathAContainer()) + then + // Use the path, which will be relative to this file, if specified + result = getPathAContainer().getRelativePath() + else ( + // Otherwise, if no code identifier was supplied, it applies to the parent container of the + // file itself + not exists(getCodeIdentifier()) and + result = this.getFile().getParentContainer().getRelativePath() + ) + ) + } + + cached + predicate isDeviated(Query query, string deviationPath) { + query = getQuery() and + deviationPath = getADeviationPath() + } +} From 08fc00ed7af1d4e5c8dc41577c28bcce73e1cde7 Mon Sep 17 00:00:00 2001 From: Mauro Baluda Date: Fri, 3 Mar 2023 11:16:21 +0100 Subject: [PATCH 06/17] Update IdentifierNameOfANonMemberObjectWithExternalOrInternalLinkageIsReused.expected --- ...MemberObjectWithExternalOrInternalLinkageIsReused.expected | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/cpp/autosar/test/rules/A2-10-5/IdentifierNameOfANonMemberObjectWithExternalOrInternalLinkageIsReused.expected b/cpp/autosar/test/rules/A2-10-5/IdentifierNameOfANonMemberObjectWithExternalOrInternalLinkageIsReused.expected index 83409a78a2..66d2b38c57 100644 --- a/cpp/autosar/test/rules/A2-10-5/IdentifierNameOfANonMemberObjectWithExternalOrInternalLinkageIsReused.expected +++ b/cpp/autosar/test/rules/A2-10-5/IdentifierNameOfANonMemberObjectWithExternalOrInternalLinkageIsReused.expected @@ -1,4 +1,6 @@ | test1a.cpp:2:12:2:13 | g1 | Identifier name of non-member object $@ reuses the identifier name of non-member object $@. | test1a.cpp:2:12:2:13 | g1 | g1 | test1b.cpp:2:12:2:13 | g1 | g1 | | test1a.cpp:6:12:6:13 | g3 | Identifier name of non-member object $@ reuses the identifier name of non-member object $@. | test1a.cpp:6:12:6:13 | g3 | g3 | test1b.cpp:6:12:6:13 | g3 | g3 | +| test1a.cpp:17:43:17:43 | number_two | Identifier name of non-member object $@ reuses the identifier name of non-member object $@. | test1a.cpp:17:43:17:43 | number_two | number_two | test1b.cpp:11:43:11:43 | number_two | number_two | | test1b.cpp:2:12:2:13 | g1 | Identifier name of non-member object $@ reuses the identifier name of non-member object $@. | test1b.cpp:2:12:2:13 | g1 | g1 | test1a.cpp:2:12:2:13 | g1 | g1 | -| test1b.cpp:6:12:6:13 | g3 | Identifier name of non-member object $@ reuses the identifier name of non-member object $@. | test1b.cpp:6:12:6:13 | g3 | g3 | test1a.cpp:6:12:6:13 | g3 | g3 | \ No newline at end of file +| test1b.cpp:6:12:6:13 | g3 | Identifier name of non-member object $@ reuses the identifier name of non-member object $@. | test1b.cpp:6:12:6:13 | g3 | g3 | test1a.cpp:6:12:6:13 | g3 | g3 | +| test1b.cpp:11:43:11:43 | number_two | Identifier name of non-member object $@ reuses the identifier name of non-member object $@. | test1b.cpp:11:43:11:43 | number_two | number_two | test1a.cpp:17:43:17:43 | number_two | number_two | From e1e31f51ef207fd6fdf81512aa2d1f75bd6a5fd8 Mon Sep 17 00:00:00 2001 From: Jeroen Ketema Date: Wed, 1 Mar 2023 10:50:35 +0100 Subject: [PATCH 07/17] Update MISRA RULE-8-4 test for changes in latest CodeQL --- .../rules/RULE-8-4/CompatibleDeclarationObjectDefined.expected | 1 - c/misra/test/rules/RULE-8-4/object1.c | 2 +- c/misra/test/rules/RULE-8-4/object2.c | 2 +- 3 files changed, 2 insertions(+), 3 deletions(-) diff --git a/c/misra/test/rules/RULE-8-4/CompatibleDeclarationObjectDefined.expected b/c/misra/test/rules/RULE-8-4/CompatibleDeclarationObjectDefined.expected index 6655c5d6f7..f8472b21e0 100644 --- a/c/misra/test/rules/RULE-8-4/CompatibleDeclarationObjectDefined.expected +++ b/c/misra/test/rules/RULE-8-4/CompatibleDeclarationObjectDefined.expected @@ -1,3 +1,2 @@ | object1.c:4:12:4:13 | definition of i1 | No separate compatible declaration found for this definition. | | object1.c:6:5:6:6 | definition of i2 | No separate compatible declaration found for this definition. | -| object2.c:1:7:1:8 | definition of i3 | No separate compatible declaration found for this definition. | diff --git a/c/misra/test/rules/RULE-8-4/object1.c b/c/misra/test/rules/RULE-8-4/object1.c index 3de20eabcc..bea41c7a20 100644 --- a/c/misra/test/rules/RULE-8-4/object1.c +++ b/c/misra/test/rules/RULE-8-4/object1.c @@ -5,6 +5,6 @@ extern int i1 = 0; // NON_COMPLIANT int i2 = 0; // NON_COMPLIANT -extern int i3; // NON_COMPLIANT +extern int i3; // NON_COMPLIANT - not detected as `short i3` exists extern int i4; // COMPLIANT \ No newline at end of file diff --git a/c/misra/test/rules/RULE-8-4/object2.c b/c/misra/test/rules/RULE-8-4/object2.c index 78c5bee421..eef1696918 100644 --- a/c/misra/test/rules/RULE-8-4/object2.c +++ b/c/misra/test/rules/RULE-8-4/object2.c @@ -1,3 +1,3 @@ -short i3 = 0; // NON_COMPLIANT +short i3 = 0; // NON_COMPLIANT - not detected as `extern int i3` exists signed int i4 = 0; // COMPLIANT \ No newline at end of file From 39f2079f139eb0f2d1c4a8561d72e5eefd890f56 Mon Sep 17 00:00:00 2001 From: Mauro Baluda Date: Fri, 3 Mar 2023 12:04:59 +0100 Subject: [PATCH 08/17] Format test case --- c/misra/test/rules/RULE-8-4/object1.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/c/misra/test/rules/RULE-8-4/object1.c b/c/misra/test/rules/RULE-8-4/object1.c index bea41c7a20..93441003ec 100644 --- a/c/misra/test/rules/RULE-8-4/object1.c +++ b/c/misra/test/rules/RULE-8-4/object1.c @@ -5,6 +5,6 @@ extern int i1 = 0; // NON_COMPLIANT int i2 = 0; // NON_COMPLIANT -extern int i3; // NON_COMPLIANT - not detected as `short i3` exists +extern int i3; // NON_COMPLIANT - not detected as `short i3` exists extern int i4; // COMPLIANT \ No newline at end of file From f723712cacfe7dc35c848be4bf8cce8fcb30fa58 Mon Sep 17 00:00:00 2001 From: Mauro Baluda Date: Mon, 6 Mar 2023 19:48:12 +0100 Subject: [PATCH 09/17] Update test1a.cpp --- cpp/autosar/test/rules/A2-10-5/test1a.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cpp/autosar/test/rules/A2-10-5/test1a.cpp b/cpp/autosar/test/rules/A2-10-5/test1a.cpp index d8e6634da7..80f63c3c69 100644 --- a/cpp/autosar/test/rules/A2-10-5/test1a.cpp +++ b/cpp/autosar/test/rules/A2-10-5/test1a.cpp @@ -1,5 +1,5 @@ namespace n1 { -static int g1 = 0; +static int g1 = 0; // NON_COMPLIANT } static int g2; // COMPLIANT From 1fd3b9c2b273801c5846533a061b8741ae5ffe0d Mon Sep 17 00:00:00 2001 From: Mauro Baluda Date: Mon, 6 Mar 2023 19:51:22 +0100 Subject: [PATCH 10/17] Update object1.c --- c/misra/test/rules/RULE-8-4/object1.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/c/misra/test/rules/RULE-8-4/object1.c b/c/misra/test/rules/RULE-8-4/object1.c index 93441003ec..9b52cd85af 100644 --- a/c/misra/test/rules/RULE-8-4/object1.c +++ b/c/misra/test/rules/RULE-8-4/object1.c @@ -5,6 +5,6 @@ extern int i1 = 0; // NON_COMPLIANT int i2 = 0; // NON_COMPLIANT -extern int i3; // NON_COMPLIANT - not detected as `short i3` exists +extern int i3; // NON_COMPLIANT[FALSE_NEGATIVE] - not detected as `short i3` exists -extern int i4; // COMPLIANT \ No newline at end of file +extern int i4; // COMPLIANT From c43701f9d83f71553b6ab5cac3f4fe954544b9ad Mon Sep 17 00:00:00 2001 From: Mauro Baluda Date: Mon, 6 Mar 2023 19:52:24 +0100 Subject: [PATCH 11/17] Update object2.c --- c/misra/test/rules/RULE-8-4/object2.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/c/misra/test/rules/RULE-8-4/object2.c b/c/misra/test/rules/RULE-8-4/object2.c index eef1696918..a308f7123b 100644 --- a/c/misra/test/rules/RULE-8-4/object2.c +++ b/c/misra/test/rules/RULE-8-4/object2.c @@ -1,3 +1,4 @@ -short i3 = 0; // NON_COMPLIANT - not detected as `extern int i3` exists +// not detected as `extern int i3` exists +short i3 = 0; // NON_COMPLIANT[FALSE_NEGATIVE] -signed int i4 = 0; // COMPLIANT \ No newline at end of file +signed int i4 = 0; // COMPLIANT From d82cafbf2654d6182ed16ec0057d046f0c98f26f Mon Sep 17 00:00:00 2001 From: Mauro Baluda Date: Mon, 6 Mar 2023 19:53:09 +0100 Subject: [PATCH 12/17] Update object1.c --- c/misra/test/rules/RULE-8-4/object1.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/c/misra/test/rules/RULE-8-4/object1.c b/c/misra/test/rules/RULE-8-4/object1.c index 9b52cd85af..c37301e56f 100644 --- a/c/misra/test/rules/RULE-8-4/object1.c +++ b/c/misra/test/rules/RULE-8-4/object1.c @@ -5,6 +5,7 @@ extern int i1 = 0; // NON_COMPLIANT int i2 = 0; // NON_COMPLIANT -extern int i3; // NON_COMPLIANT[FALSE_NEGATIVE] - not detected as `short i3` exists +// not detected as `short i3` exists +extern int i3; // NON_COMPLIANT[FALSE_NEGATIVE] extern int i4; // COMPLIANT From 4f4dc37657549e59ea0476f5c2f6f2e55c5dd969 Mon Sep 17 00:00:00 2001 From: Mauro Baluda Date: Mon, 6 Mar 2023 20:11:47 +0100 Subject: [PATCH 13/17] Remove submodule codeql --- .gitmodules | 3 --- codeql_modules/codeql | 1 - 2 files changed, 4 deletions(-) delete mode 100644 .gitmodules delete mode 160000 codeql_modules/codeql diff --git a/.gitmodules b/.gitmodules deleted file mode 100644 index af8560fc44..0000000000 --- a/.gitmodules +++ /dev/null @@ -1,3 +0,0 @@ -[submodule "codeql"] - path = codeql_modules/codeql - url = https://github.com/github/codeql.git diff --git a/codeql_modules/codeql b/codeql_modules/codeql deleted file mode 160000 index 28fe7a7660..0000000000 --- a/codeql_modules/codeql +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 28fe7a76603ab7ef884ca35115b63104ecb699a7 From 5e8e2ffd072619c554a161d34dd2bd4faf17ef52 Mon Sep 17 00:00:00 2001 From: Mauro Baluda Date: Thu, 9 Mar 2023 01:05:03 +0100 Subject: [PATCH 14/17] Fix RULE-8-4 --- .../CompatibleDeclarationObjectDefined.ql | 16 +++++----------- ...CompatibleDeclarationFunctionDefined.expected | 5 +++-- c/misra/test/rules/RULE-8-4/object1.c | 7 +++---- c/misra/test/rules/RULE-8-4/object2.c | 3 +-- c/misra/test/rules/RULE-8-4/test.c | 0 5 files changed, 12 insertions(+), 19 deletions(-) delete mode 100644 c/misra/test/rules/RULE-8-4/test.c diff --git a/c/misra/src/rules/RULE-8-4/CompatibleDeclarationObjectDefined.ql b/c/misra/src/rules/RULE-8-4/CompatibleDeclarationObjectDefined.ql index 7b0e194afb..817539c51c 100644 --- a/c/misra/src/rules/RULE-8-4/CompatibleDeclarationObjectDefined.ql +++ b/c/misra/src/rules/RULE-8-4/CompatibleDeclarationObjectDefined.ql @@ -23,16 +23,10 @@ where not isExcluded(decl1, Declarations4Package::compatibleDeclarationObjectDefinedQuery()) and decl1.isDefinition() and decl1.getDeclaration() instanceof ExternalIdentifiers and - ( - //no declaration matches exactly - not exists(VariableDeclarationEntry decl2 | - not decl2.isDefinition() and decl2.getDeclaration() = decl1.getDeclaration() - ) and - //and none is close enough - not exists(VariableDeclarationEntry decl2 | - not decl2.isDefinition() and - decl1.getVariable().getQualifiedName() = decl2.getVariable().getQualifiedName() and - typesCompatible(decl1.getType(), decl2.getType()) - ) + // no declaration matches + not exists(VariableDeclarationEntry decl2 | + not decl2.isDefinition() and + decl1.getVariable().getQualifiedName() = decl2.getVariable().getQualifiedName() and + typesCompatible(decl1.getType(), decl2.getType()) ) select decl1, "No separate compatible declaration found for this definition." diff --git a/c/misra/test/rules/RULE-8-4/CompatibleDeclarationFunctionDefined.expected b/c/misra/test/rules/RULE-8-4/CompatibleDeclarationFunctionDefined.expected index 9153fafa97..6655c5d6f7 100644 --- a/c/misra/test/rules/RULE-8-4/CompatibleDeclarationFunctionDefined.expected +++ b/c/misra/test/rules/RULE-8-4/CompatibleDeclarationFunctionDefined.expected @@ -1,2 +1,3 @@ -| function2.c:5:6:5:7 | definition of f3 | No separate compatible declaration found for this definition. | -| function2.c:7:6:7:7 | definition of f4 | No separate compatible declaration found for this definition. | +| object1.c:4:12:4:13 | definition of i1 | No separate compatible declaration found for this definition. | +| object1.c:6:5:6:6 | definition of i2 | No separate compatible declaration found for this definition. | +| object2.c:1:7:1:8 | definition of i3 | No separate compatible declaration found for this definition. | diff --git a/c/misra/test/rules/RULE-8-4/object1.c b/c/misra/test/rules/RULE-8-4/object1.c index c37301e56f..7504bb9327 100644 --- a/c/misra/test/rules/RULE-8-4/object1.c +++ b/c/misra/test/rules/RULE-8-4/object1.c @@ -1,11 +1,10 @@ extern int i; -i = 0; // COMPLIANT +int i = 0; // COMPLIANT extern int i1 = 0; // NON_COMPLIANT int i2 = 0; // NON_COMPLIANT -// not detected as `short i3` exists -extern int i3; // NON_COMPLIANT[FALSE_NEGATIVE] +extern int i3; -extern int i4; // COMPLIANT +extern int i4; diff --git a/c/misra/test/rules/RULE-8-4/object2.c b/c/misra/test/rules/RULE-8-4/object2.c index a308f7123b..e432fcb29b 100644 --- a/c/misra/test/rules/RULE-8-4/object2.c +++ b/c/misra/test/rules/RULE-8-4/object2.c @@ -1,4 +1,3 @@ -// not detected as `extern int i3` exists -short i3 = 0; // NON_COMPLIANT[FALSE_NEGATIVE] +short i3 = 0; // NON_COMPLIANT signed int i4 = 0; // COMPLIANT diff --git a/c/misra/test/rules/RULE-8-4/test.c b/c/misra/test/rules/RULE-8-4/test.c deleted file mode 100644 index e69de29bb2..0000000000 From 49b19197e55454eed07c2ebfed82f7a5db424687 Mon Sep 17 00:00:00 2001 From: Mauro Baluda Date: Thu, 9 Mar 2023 01:10:50 +0100 Subject: [PATCH 15/17] Fix RULE-8-4 expected files --- .../RULE-8-4/CompatibleDeclarationFunctionDefined.expected | 5 ++--- .../RULE-8-4/CompatibleDeclarationObjectDefined.expected | 1 + 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/c/misra/test/rules/RULE-8-4/CompatibleDeclarationFunctionDefined.expected b/c/misra/test/rules/RULE-8-4/CompatibleDeclarationFunctionDefined.expected index 6655c5d6f7..9153fafa97 100644 --- a/c/misra/test/rules/RULE-8-4/CompatibleDeclarationFunctionDefined.expected +++ b/c/misra/test/rules/RULE-8-4/CompatibleDeclarationFunctionDefined.expected @@ -1,3 +1,2 @@ -| object1.c:4:12:4:13 | definition of i1 | No separate compatible declaration found for this definition. | -| object1.c:6:5:6:6 | definition of i2 | No separate compatible declaration found for this definition. | -| object2.c:1:7:1:8 | definition of i3 | No separate compatible declaration found for this definition. | +| function2.c:5:6:5:7 | definition of f3 | No separate compatible declaration found for this definition. | +| function2.c:7:6:7:7 | definition of f4 | No separate compatible declaration found for this definition. | diff --git a/c/misra/test/rules/RULE-8-4/CompatibleDeclarationObjectDefined.expected b/c/misra/test/rules/RULE-8-4/CompatibleDeclarationObjectDefined.expected index f8472b21e0..6655c5d6f7 100644 --- a/c/misra/test/rules/RULE-8-4/CompatibleDeclarationObjectDefined.expected +++ b/c/misra/test/rules/RULE-8-4/CompatibleDeclarationObjectDefined.expected @@ -1,2 +1,3 @@ | object1.c:4:12:4:13 | definition of i1 | No separate compatible declaration found for this definition. | | object1.c:6:5:6:6 | definition of i2 | No separate compatible declaration found for this definition. | +| object2.c:1:7:1:8 | definition of i3 | No separate compatible declaration found for this definition. | From 8a61a0d9967ad08e31a8440e8602a2ae9ca7ce0a Mon Sep 17 00:00:00 2001 From: Mauro Baluda Date: Thu, 9 Mar 2023 01:27:12 +0100 Subject: [PATCH 16/17] Rule-8-4 --- .../src/rules/RULE-8-4/CompatibleDeclarationObjectDefined.ql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/c/misra/src/rules/RULE-8-4/CompatibleDeclarationObjectDefined.ql b/c/misra/src/rules/RULE-8-4/CompatibleDeclarationObjectDefined.ql index 817539c51c..433597cf4a 100644 --- a/c/misra/src/rules/RULE-8-4/CompatibleDeclarationObjectDefined.ql +++ b/c/misra/src/rules/RULE-8-4/CompatibleDeclarationObjectDefined.ql @@ -26,7 +26,7 @@ where // no declaration matches not exists(VariableDeclarationEntry decl2 | not decl2.isDefinition() and - decl1.getVariable().getQualifiedName() = decl2.getVariable().getQualifiedName() and + decl1.getDeclaration() = decl2.getDeclaration() and typesCompatible(decl1.getType(), decl2.getType()) ) select decl1, "No separate compatible declaration found for this definition." From 0844615534899f2e0dfb0ee7d6ae268a9561c8fb Mon Sep 17 00:00:00 2001 From: Mauro Baluda Date: Thu, 9 Mar 2023 01:53:33 +0100 Subject: [PATCH 17/17] Add change notes --- change_notes/2022-03-08-update-to-CodeQL-2.10.5.md | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 change_notes/2022-03-08-update-to-CodeQL-2.10.5.md diff --git a/change_notes/2022-03-08-update-to-CodeQL-2.10.5.md b/change_notes/2022-03-08-update-to-CodeQL-2.10.5.md new file mode 100644 index 0000000000..7b08c18c41 --- /dev/null +++ b/change_notes/2022-03-08-update-to-CodeQL-2.10.5.md @@ -0,0 +1,3 @@ +- `RULE-8-4` - `CompatibleDeclarationObjectDefined.ql` + - Update rule implementation based on changes in the CodeQL libraries. +- Updated the CodeQL version to `2.10.5`. \ No newline at end of file