From e793f83edea54182ab57a19e3074cdd46869139f Mon Sep 17 00:00:00 2001 From: Kristen Newbury Date: Fri, 30 Jan 2026 16:43:18 -0500 Subject: [PATCH 1/3] Add trigraph rule for RULE-5-0-1 --- .vscode/tasks.json | 1 + .../cpp/exclusions/cpp/RuleMetadata.qll | 3 ++ .../cpp/exclusions/cpp/Trigraph.qll | 26 +++++++++++++++++ .../TrigraphLikeSequencesShouldNotBeUsed.ql | 24 ++++++++++++++++ ...graphLikeSequencesShouldNotBeUsed.expected | 9 ++++++ ...TrigraphLikeSequencesShouldNotBeUsed.qlref | 1 + cpp/misra/test/rules/RULE-5-0-1/test.cpp | 12 ++++++++ rule_packages/cpp/Trigraph.json | 28 +++++++++++++++++++ 8 files changed, 104 insertions(+) create mode 100644 cpp/common/src/codingstandards/cpp/exclusions/cpp/Trigraph.qll create mode 100644 cpp/misra/src/rules/RULE-5-0-1/TrigraphLikeSequencesShouldNotBeUsed.ql create mode 100644 cpp/misra/test/rules/RULE-5-0-1/TrigraphLikeSequencesShouldNotBeUsed.expected create mode 100644 cpp/misra/test/rules/RULE-5-0-1/TrigraphLikeSequencesShouldNotBeUsed.qlref create mode 100644 cpp/misra/test/rules/RULE-5-0-1/test.cpp create mode 100644 rule_packages/cpp/Trigraph.json 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..ed9568bb70 --- /dev/null +++ b/cpp/misra/test/rules/RULE-5-0-1/TrigraphLikeSequencesShouldNotBeUsed.expected @@ -0,0 +1,9 @@ +| test.cpp:1:18:1:22 | ??= | Trigraph-like sequence used in string literal. | +| test.cpp:2:19:2:23 | ??/ | Trigraph-like sequence used in string literal. | +| test.cpp:3:19:3:23 | ??' | Trigraph-like sequence used in string literal. | +| test.cpp:4:19:4:23 | ??( | Trigraph-like sequence used in string literal. | +| test.cpp:5:19:5:23 | ??) | Trigraph-like sequence used in string literal. | +| test.cpp:6:19:6:23 | ??! | Trigraph-like sequence used in string literal. | +| test.cpp:7:19:7:23 | ??< | Trigraph-like sequence used in string literal. | +| test.cpp:8:19:8:23 | ??> | Trigraph-like sequence used in string literal. | +| test.cpp:9:19:9:23 | ??- | 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..b34d03092e --- /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[FALSE_POSITIVE] +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 From 403e9d198cb142a0e86f97c8f354009ab4555ba2 Mon Sep 17 00:00:00 2001 From: Kristen Newbury Date: Fri, 30 Jan 2026 16:47:44 -0500 Subject: [PATCH 2/3] Format test --- ...graphLikeSequencesShouldNotBeUsed.expected | 18 +++++++-------- cpp/misra/test/rules/RULE-5-0-1/test.cpp | 22 +++++++++---------- 2 files changed, 20 insertions(+), 20 deletions(-) diff --git a/cpp/misra/test/rules/RULE-5-0-1/TrigraphLikeSequencesShouldNotBeUsed.expected b/cpp/misra/test/rules/RULE-5-0-1/TrigraphLikeSequencesShouldNotBeUsed.expected index ed9568bb70..b2df55cee7 100644 --- a/cpp/misra/test/rules/RULE-5-0-1/TrigraphLikeSequencesShouldNotBeUsed.expected +++ b/cpp/misra/test/rules/RULE-5-0-1/TrigraphLikeSequencesShouldNotBeUsed.expected @@ -1,9 +1,9 @@ -| test.cpp:1:18:1:22 | ??= | Trigraph-like sequence used in string literal. | -| test.cpp:2:19:2:23 | ??/ | Trigraph-like sequence used in string literal. | -| test.cpp:3:19:3:23 | ??' | Trigraph-like sequence used in string literal. | -| test.cpp:4:19:4:23 | ??( | Trigraph-like sequence used in string literal. | -| test.cpp:5:19:5:23 | ??) | Trigraph-like sequence used in string literal. | -| test.cpp:6:19:6:23 | ??! | Trigraph-like sequence used in string literal. | -| test.cpp:7:19:7:23 | ??< | Trigraph-like sequence used in string literal. | -| test.cpp:8:19:8:23 | ??> | Trigraph-like sequence used in string literal. | -| test.cpp:9:19:9:23 | ??- | Trigraph-like sequence used in string literal. | +| 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/test.cpp b/cpp/misra/test/rules/RULE-5-0-1/test.cpp index b34d03092e..4f02b1a0e2 100644 --- a/cpp/misra/test/rules/RULE-5-0-1/test.cpp +++ b/cpp/misra/test/rules/RULE-5-0-1/test.cpp @@ -1,12 +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 *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[FALSE_POSITIVE] -const char * g10 = "?="; // COMPLIANT \ No newline at end of file +const char *g9 = "\?\?="; // COMPLIANT[FALSE_POSITIVE] +const char *g10 = "?="; // COMPLIANT \ No newline at end of file From 52e383a776bef6acf1509055dde6ee684358b6da Mon Sep 17 00:00:00 2001 From: Kristen Newbury Date: Fri, 30 Jan 2026 16:48:22 -0500 Subject: [PATCH 3/3] Fix incorrect testcase annotation --- cpp/misra/test/rules/RULE-5-0-1/test.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cpp/misra/test/rules/RULE-5-0-1/test.cpp b/cpp/misra/test/rules/RULE-5-0-1/test.cpp index 4f02b1a0e2..82a49279b4 100644 --- a/cpp/misra/test/rules/RULE-5-0-1/test.cpp +++ b/cpp/misra/test/rules/RULE-5-0-1/test.cpp @@ -8,5 +8,5 @@ const char *g6 = "??<"; // NON_COMPLIANT const char *g7 = "??>"; // NON_COMPLIANT const char *g8 = "??-"; // NON_COMPLIANT -const char *g9 = "\?\?="; // COMPLIANT[FALSE_POSITIVE] +const char *g9 = "\?\?="; // COMPLIANT const char *g10 = "?="; // COMPLIANT \ No newline at end of file