Skip to content

Commit 367a18a

Browse files
committed
Rule 25.5.1 - LocaleGlobalFunctionNotAllowed.ql
Add query for banned locale functions. [a]
1 parent 18e0143 commit 367a18a

File tree

4 files changed

+85
-0
lines changed

4 files changed

+85
-0
lines changed
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
/**
2+
* @id cpp/misra/locale-global-function-not-allowed
3+
* @name RULE-25-5-1: The setlocale and std::locale::global functions shall not be called
4+
* @description Calling setlocale or std::locale::global functions can introduce data races with
5+
* functions that use the locale, leading to undefined behavior.
6+
* @kind problem
7+
* @precision very-high
8+
* @problem.severity error
9+
* @tags external/misra/id/rule-25-5-1
10+
* scope/single-translation-unit
11+
* external/misra/enforcement/decidable
12+
* external/misra/obligation/required
13+
*/
14+
15+
import cpp
16+
import codingstandards.cpp.misra
17+
import codingstandards.cpp.BannedFunctions
18+
19+
class BannedLocaleFunction extends Function {
20+
BannedLocaleFunction() {
21+
this.hasGlobalOrStdName("setlocale") or
22+
this.hasQualifiedName("std", "locale", "global")
23+
}
24+
}
25+
26+
from BannedFunctions<BannedLocaleFunction>::Use use
27+
where not isExcluded(use, BannedAPIsPackage::localeGlobalFunctionNotAllowedQuery())
28+
select use, use.getAction() + " banned function '" + use.getFunctionName() + "' from <locale>."
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
| test.cpp:6:3:6:16 | call to setlocale | Call to banned function 'setlocale' from <locale>. |
2+
| test.cpp:7:3:7:16 | call to setlocale | Call to banned function 'setlocale' from <locale>. |
3+
| test.cpp:8:3:8:16 | call to setlocale | Call to banned function 'setlocale' from <locale>. |
4+
| test.cpp:12:3:12:21 | call to global | Call to banned function 'global' from <locale>. |
5+
| test.cpp:13:3:13:21 | call to global | Call to banned function 'global' from <locale>. |
6+
| test.cpp:36:5:36:18 | call to setlocale | Call to banned function 'setlocale' from <locale>. |
7+
| test.cpp:40:5:40:18 | call to setlocale | Call to banned function 'setlocale' from <locale>. |
8+
| test.cpp:45:3:45:21 | call to global | Call to banned function 'global' from <locale>. |
9+
| test.cpp:46:3:46:21 | call to global | Call to banned function 'global' from <locale>. |
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
rules/RULE-25-5-1/LocaleGlobalFunctionNotAllowed.ql
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
#include <cctype>
2+
#include <clocale>
3+
#include <locale>
4+
5+
void test_setlocale_call() {
6+
std::setlocale(LC_ALL, "C"); // NON_COMPLIANT
7+
std::setlocale(LC_NUMERIC, "C"); // NON_COMPLIANT
8+
std::setlocale(LC_TIME, "en_US.UTF-8"); // NON_COMPLIANT
9+
}
10+
11+
void test_locale_global_call() {
12+
std::locale::global(std::locale("C")); // NON_COMPLIANT
13+
std::locale::global(std::locale::classic()); // NON_COMPLIANT
14+
}
15+
16+
void test_compliant_locale_usage() {
17+
wchar_t l1 = L'\u2002';
18+
std::locale l2("C");
19+
20+
if (std::isspace(l1, l2)) { // COMPLIANT
21+
}
22+
if (std::isalpha(l1, l2)) { // COMPLIANT
23+
}
24+
if (std::isdigit(l1, l2)) { // COMPLIANT
25+
}
26+
}
27+
28+
void test_compliant_locale_construction() {
29+
std::locale l3("C"); // COMPLIANT
30+
std::locale l4 = std::locale::classic(); // COMPLIANT
31+
std::locale l5; // COMPLIANT
32+
}
33+
34+
void test_nested_setlocale_calls() {
35+
if (true) {
36+
std::setlocale(LC_ALL, "ja_JP.utf8"); // NON_COMPLIANT
37+
}
38+
39+
for (int l6 = 0; l6 < 1; ++l6) {
40+
std::setlocale(LC_CTYPE, "C"); // NON_COMPLIANT
41+
}
42+
}
43+
44+
void test_locale_global_with_different_locales() {
45+
std::locale::global(std::locale("en_US.UTF-8")); // NON_COMPLIANT
46+
std::locale::global(std::locale("ja_JP.utf8")); // NON_COMPLIANT
47+
}

0 commit comments

Comments
 (0)