diff --git a/.vscode/tasks.json b/.vscode/tasks.json index 74f065ac3b..89edb96e71 100644 --- a/.vscode/tasks.json +++ b/.vscode/tasks.json @@ -290,6 +290,7 @@ "Strings3", "Syntax", "Templates", + "Trigraph", "TypeRanges", "Lambdas", "Pointers", diff --git a/cpp/common/src/codingstandards/cpp/exclusions/cpp/RuleMetadata.qll b/cpp/common/src/codingstandards/cpp/exclusions/cpp/RuleMetadata.qll index 53e798c48a..700ee6b040 100644 --- a/cpp/common/src/codingstandards/cpp/exclusions/cpp/RuleMetadata.qll +++ b/cpp/common/src/codingstandards/cpp/exclusions/cpp/RuleMetadata.qll @@ -59,6 +59,7 @@ import Statements import Strings import Templates import Toolchain +import Trigraph import TrustBoundaries import TypeRanges import Uninitialized @@ -123,6 +124,7 @@ newtype TCPPQuery = TStringsPackageQuery(StringsQuery q) or TTemplatesPackageQuery(TemplatesQuery q) or TToolchainPackageQuery(ToolchainQuery q) or + TTrigraphPackageQuery(TrigraphQuery q) or TTrustBoundariesPackageQuery(TrustBoundariesQuery q) or TTypeRangesPackageQuery(TypeRangesQuery q) or TUninitializedPackageQuery(UninitializedQuery q) or @@ -187,6 +189,7 @@ predicate isQueryMetadata(Query query, string queryId, string ruleId, string cat isStringsQueryMetadata(query, queryId, ruleId, category) or isTemplatesQueryMetadata(query, queryId, ruleId, category) or isToolchainQueryMetadata(query, queryId, ruleId, category) or + isTrigraphQueryMetadata(query, queryId, ruleId, category) or isTrustBoundariesQueryMetadata(query, queryId, ruleId, category) or isTypeRangesQueryMetadata(query, queryId, ruleId, category) or isUninitializedQueryMetadata(query, queryId, ruleId, category) or diff --git a/cpp/common/src/codingstandards/cpp/exclusions/cpp/Trigraph.qll b/cpp/common/src/codingstandards/cpp/exclusions/cpp/Trigraph.qll new file mode 100644 index 0000000000..15de4ab2a7 --- /dev/null +++ b/cpp/common/src/codingstandards/cpp/exclusions/cpp/Trigraph.qll @@ -0,0 +1,26 @@ +//** THIS FILE IS AUTOGENERATED, DO NOT MODIFY DIRECTLY. **/ +import cpp +import RuleMetadata +import codingstandards.cpp.exclusions.RuleMetadata + +newtype TrigraphQuery = TTrigraphLikeSequencesShouldNotBeUsedQuery() + +predicate isTrigraphQueryMetadata(Query query, string queryId, string ruleId, string category) { + query = + // `Query` instance for the `trigraphLikeSequencesShouldNotBeUsed` query + TrigraphPackage::trigraphLikeSequencesShouldNotBeUsedQuery() and + queryId = + // `@id` for the `trigraphLikeSequencesShouldNotBeUsed` query + "cpp/misra/trigraph-like-sequences-should-not-be-used" and + ruleId = "RULE-5-0-1" and + category = "advisory" +} + +module TrigraphPackage { + Query trigraphLikeSequencesShouldNotBeUsedQuery() { + //autogenerate `Query` type + result = + // `Query` type for `trigraphLikeSequencesShouldNotBeUsed` query + TQueryCPP(TTrigraphPackageQuery(TTrigraphLikeSequencesShouldNotBeUsedQuery())) + } +} diff --git a/cpp/misra/src/rules/RULE-5-0-1/TrigraphLikeSequencesShouldNotBeUsed.ql b/cpp/misra/src/rules/RULE-5-0-1/TrigraphLikeSequencesShouldNotBeUsed.ql new file mode 100644 index 0000000000..074240dc70 --- /dev/null +++ b/cpp/misra/src/rules/RULE-5-0-1/TrigraphLikeSequencesShouldNotBeUsed.ql @@ -0,0 +1,24 @@ +/** + * @id cpp/misra/trigraph-like-sequences-should-not-be-used + * @name RULE-5-0-1: Trigraph-like sequences should not be used + * @description Using trigraph-like sequences can lead to developer confusion. + * @kind problem + * @precision medium + * @problem.severity warning + * @tags external/misra/id/rule-5-0-1 + * readability + * scope/single-translation-unit + * external/misra/enforcement/decidable + * external/misra/obligation/advisory + */ + +import cpp +import codingstandards.cpp.misra + +from StringLiteral s, int occurrenceOffset +where + not isExcluded(s, TrigraphPackage::trigraphLikeSequencesShouldNotBeUsedQuery()) and + exists(s.getValue().regexpFind("\\?\\?[=/'()!<>-]", _, occurrenceOffset)) and + //one escape character is enough to mean this isnt a trigraph-like sequence + not exists(s.getASimpleEscapeSequence(_, occurrenceOffset + 1)) +select s, "Trigraph-like sequence used in string literal." diff --git a/cpp/misra/test/rules/RULE-5-0-1/TrigraphLikeSequencesShouldNotBeUsed.expected b/cpp/misra/test/rules/RULE-5-0-1/TrigraphLikeSequencesShouldNotBeUsed.expected new file mode 100644 index 0000000000..b2df55cee7 --- /dev/null +++ b/cpp/misra/test/rules/RULE-5-0-1/TrigraphLikeSequencesShouldNotBeUsed.expected @@ -0,0 +1,9 @@ +| test.cpp:1:17:1:21 | ??= | Trigraph-like sequence used in string literal. | +| test.cpp:2:18:2:22 | ??/ | Trigraph-like sequence used in string literal. | +| test.cpp:3:18:3:22 | ??' | Trigraph-like sequence used in string literal. | +| test.cpp:4:18:4:22 | ??( | Trigraph-like sequence used in string literal. | +| test.cpp:5:18:5:22 | ??) | Trigraph-like sequence used in string literal. | +| test.cpp:6:18:6:22 | ??! | Trigraph-like sequence used in string literal. | +| test.cpp:7:18:7:22 | ??< | Trigraph-like sequence used in string literal. | +| test.cpp:8:18:8:22 | ??> | Trigraph-like sequence used in string literal. | +| test.cpp:9:18:9:22 | ??- | Trigraph-like sequence used in string literal. | diff --git a/cpp/misra/test/rules/RULE-5-0-1/TrigraphLikeSequencesShouldNotBeUsed.qlref b/cpp/misra/test/rules/RULE-5-0-1/TrigraphLikeSequencesShouldNotBeUsed.qlref new file mode 100644 index 0000000000..efc064ec69 --- /dev/null +++ b/cpp/misra/test/rules/RULE-5-0-1/TrigraphLikeSequencesShouldNotBeUsed.qlref @@ -0,0 +1 @@ +rules/RULE-5-0-1/TrigraphLikeSequencesShouldNotBeUsed.ql \ No newline at end of file diff --git a/cpp/misra/test/rules/RULE-5-0-1/test.cpp b/cpp/misra/test/rules/RULE-5-0-1/test.cpp new file mode 100644 index 0000000000..82a49279b4 --- /dev/null +++ b/cpp/misra/test/rules/RULE-5-0-1/test.cpp @@ -0,0 +1,12 @@ +const char *g = "??="; // NON_COMPLIANT +const char *g1 = "??/"; // NON_COMPLIANT +const char *g2 = "??'"; // NON_COMPLIANT +const char *g3 = "??("; // NON_COMPLIANT +const char *g4 = "??)"; // NON_COMPLIANT +const char *g5 = "??!"; // NON_COMPLIANT +const char *g6 = "??<"; // NON_COMPLIANT +const char *g7 = "??>"; // NON_COMPLIANT +const char *g8 = "??-"; // NON_COMPLIANT + +const char *g9 = "\?\?="; // COMPLIANT +const char *g10 = "?="; // COMPLIANT \ No newline at end of file diff --git a/rule_packages/cpp/Trigraph.json b/rule_packages/cpp/Trigraph.json new file mode 100644 index 0000000000..5234902ea8 --- /dev/null +++ b/rule_packages/cpp/Trigraph.json @@ -0,0 +1,28 @@ +{ + "MISRA-C++-2023": { + "RULE-5-0-1": { + "properties": { + "enforcement": "decidable", + "obligation": "advisory" + }, + "queries": [ + { + "description": "Using trigraph-like sequences can lead to developer confusion.", + "kind": "problem", + "name": "Trigraph-like sequences should not be used", + "precision": "medium", + "severity": "warning", + "short_name": "TrigraphLikeSequencesShouldNotBeUsed", + "tags": [ + "readability", + "scope/single-translation-unit" + ], + "implementation_scope": { + "description": "The rule checks within string literals only for trigraph-like sequences." + } + } + ], + "title": "Trigraph-like sequences should not be used" + } + } +} \ No newline at end of file