diff --git a/change_notes/2024-01-17-fix-reported-fp-for-a2-3-1.md b/change_notes/2024-01-17-fix-reported-fp-for-a2-3-1.md new file mode 100644 index 0000000000..0ac0580506 --- /dev/null +++ b/change_notes/2024-01-17-fix-reported-fp-for-a2-3-1.md @@ -0,0 +1,2 @@ +`A2-3-1`: ` cpp/autosar/invalid-character-in-string-literal` + - Fixes #311. Exclude wide string literals and utf8 string literal. \ No newline at end of file diff --git a/cpp/autosar/src/rules/A2-3-1/InvalidCharacterInStringLiteral.ql b/cpp/autosar/src/rules/A2-3-1/InvalidCharacterInStringLiteral.ql index 93109bcd30..4f215d7d9c 100644 --- a/cpp/autosar/src/rules/A2-3-1/InvalidCharacterInStringLiteral.ql +++ b/cpp/autosar/src/rules/A2-3-1/InvalidCharacterInStringLiteral.ql @@ -17,6 +17,7 @@ import cpp import codingstandards.cpp.autosar +import codingstandards.cpp.Literals bindingset[s] string getCharOutsideBasicSourceCharSet(string s) { @@ -27,6 +28,9 @@ string getCharOutsideBasicSourceCharSet(string s) { from StringLiteral s, string ch where not isExcluded(s, NamingPackage::invalidCharacterInStringLiteralQuery()) and - ch = getCharOutsideBasicSourceCharSet(s.getValueText()) + ch = getCharOutsideBasicSourceCharSet(s.getValueText()) and + // wide string and utf8 string literals are exempted. + not s instanceof WideStringLiteral and + not s instanceof Utf8StringLiteral select s, "String literal uses the character '" + ch + "' that is outside the language basic character set." diff --git a/cpp/autosar/test/rules/A2-3-1/InvalidCharacterInComment.expected b/cpp/autosar/test/rules/A2-3-1/InvalidCharacterInComment.expected index b5fd4c77cc..4df213e5c2 100644 --- a/cpp/autosar/test/rules/A2-3-1/InvalidCharacterInComment.expected +++ b/cpp/autosar/test/rules/A2-3-1/InvalidCharacterInComment.expected @@ -1,2 +1,2 @@ | test.cpp:3:1:3:37 | // Invalid character \u00ce\u00b1 NON_COMPLIANT | Comment uses the character '\u00ce\u00b1' that is outside the language basic character set. | -| test.cpp:10:1:12:2 | /*\nInvalid character \u00e2\u0086\u00a6 NON_COMPLIANT\n*/ | Comment uses the character '\u00e2\u0086\u00a6' that is outside the language basic character set. | +| test.cpp:12:1:14:2 | /*\nInvalid character \u00e2\u0086\u00a6 NON_COMPLIANT\n*/ | Comment uses the character '\u00e2\u0086\u00a6' that is outside the language basic character set. | diff --git a/cpp/autosar/test/rules/A2-3-1/InvalidCharacterInStringLiteral.expected b/cpp/autosar/test/rules/A2-3-1/InvalidCharacterInStringLiteral.expected index 3ad38685ba..fe21bce430 100644 --- a/cpp/autosar/test/rules/A2-3-1/InvalidCharacterInStringLiteral.expected +++ b/cpp/autosar/test/rules/A2-3-1/InvalidCharacterInStringLiteral.expected @@ -1 +1 @@ -| test.cpp:7:20:7:22 | \u00ce\u00b1 | String literal uses the character '\u03b1' that is outside the language basic character set. | +| test.cpp:7:21:7:23 | \u00ce\u00b1 | String literal uses the character '\u03b1' that is outside the language basic character set. | diff --git a/cpp/autosar/test/rules/A2-3-1/test.cpp b/cpp/autosar/test/rules/A2-3-1/test.cpp index 5d1550f292..cc8b1b53ac 100644 --- a/cpp/autosar/test/rules/A2-3-1/test.cpp +++ b/cpp/autosar/test/rules/A2-3-1/test.cpp @@ -4,9 +4,15 @@ double α = 2.; // NON_COMPLIANT; U+03b1 void *to_𐆅_and_beyond = nullptr; // NON_COMPLIANT; U+10185 int l1_\u00A8; // COMPLIANT[FALSE_POSITIVE] -const char *euro = "α"; // NON_COMPLIANT +const char *euro1 = "α"; // NON_COMPLIANT +const wchar_t *euro2 = L"α"; // COMPLIANT +const char *euro3 = u8"α"; // COMPLIANT int valid; /* Invalid character ↦ NON_COMPLIANT +*/ + +/* +Valid character @ in comments COMPLIANT */ \ No newline at end of file diff --git a/cpp/common/src/codingstandards/cpp/Literals.qll b/cpp/common/src/codingstandards/cpp/Literals.qll index 0a6a40aa19..d4e11154fa 100644 --- a/cpp/common/src/codingstandards/cpp/Literals.qll +++ b/cpp/common/src/codingstandards/cpp/Literals.qll @@ -12,3 +12,19 @@ string getTruncatedLiteralText(Literal l) { else result = text ) } + +class WideStringLiteral extends StringLiteral { + WideStringLiteral() { this.getValueText().regexpMatch("(?s)\\s*L\".*") } +} + +class Utf8StringLiteral extends StringLiteral { + Utf8StringLiteral() { this.getValueText().regexpMatch("(?s)\\s*u8\".*") } +} + +class Utf16StringLiteral extends StringLiteral { + Utf16StringLiteral() { this.getValueText().regexpMatch("(?s)\\s*u\".*") } +} + +class Utf32StringLiteral extends StringLiteral { + Utf32StringLiteral() { this.getValueText().regexpMatch("(?s)\\s*U\".*") } +}