Miscellaneous-AnsiStringUse¶
Use wide strings when calling the Microsoft C/C++ standard library
Required inputs: IR
Rationale
For portable applications, the recommendation is to use UTF-8 as string encoding.
However, on Windows, this is problematic because the standard library expects char*
strings to use the system ANSI codepage.
Moreover, it is impossible to access all files when passing file names as char*
to the standard library, because some file names may contain Unicode characters that have no
representation in the ANSI codepage.
In order to use UTF-8 internally in the application, all strings must be converted to/from wide-strings when calling Microsoft APIs. Even if UTF-8 is not used internally, the ANSI APIs must be avoided.
You should only enable this rule when analyzing a Windows build of your application.
On other platforms, the normal functions taking char* can be used with UTF-8.
Windows API
This rule only verifies calls to functions from the Microsoft C/C++ standard library. It does not verify direct calls to the Windows API. You should#define UNICODE and _UNICODE to use the Windows API
with wide strings.
Example
void open_file(const std::string& filename)
{
std::ifstream f1(filename); // Not compliant:
// 'filename' is interpreted using the ANSI codepage
std::ifstream f2(widen(filename)); // Compliant.
}
widen() is a helper function that converts from UTF-8 std::string
to std::wstring on Windows. On other platforms, it returns the std::string
without any conversion.
See Also
https://utf8everywhere.org/#windowsPossible Messages
Key |
Text |
Severity |
Disabled |
|---|---|---|---|
ansi_console_call |
Use of ANSI string for Windows console API. |
None |
False |
ansi_env_call |
Access to environment using ANSI strings. |
None |
False |
ansi_exec_call |
Process start using ANSI strings. |
None |
False |
ansi_file_call |
Use of ANSI string for file path. |
None |
False |
ansi_time_call |
Use of ANSI string for time API. |
None |
True |
Options¶
This rule shares the following common options: exclude_in_macros, exclude_messages_in_system_headers, excludes, extend_exclude_to_macro_invocations, includes, justification_checker, languages, post_processing, provider, report_at, severity
The following places define options that affect this rule: Stylechecks, Analysis-GlobalOptions
stdlib_console_functions¶
stdlib_console_functions
Mapping from console function names to the index of the string parameter.Type: dict[bauhaus.analysis.config.QualifiedName, int]
Default:
{ '_cgets_s': 0, '_cprintf': 0, '_cprintf_l': 0, '_cprintf_p': 0, '_cprintf_p_l': 0, '_cprintf_s': 0, '_cprintf_s_l': 0, '_cputs': 0, '_cscanf': 0, '_cscanf_l': 0, '_cscanf_s': 0, '_cscanf_s_l': 0, '_getch': -1, '_getch_nolock': -1, '_getche': -1, '_getche_nolock': -1, 'cgets': 0, 'cprintf': 0, 'cputs': 0, 'cscanf': 0, 'getch': -1, 'getche': -1 }
stdlib_env_functions¶
stdlib_env_functions
Mapping from environment function names to the index of the string parameter.Type: dict[bauhaus.analysis.config.QualifiedName, int]
Default:
{ '_dupenv_s': 0, '_dupenv_s_dbg': 0, '_putenv': 0, '_putenv_s': 0, '_searchenv': 0, '_searchenv_s': 0, 'getenv': -1, 'getenv_s': 1, 'putenv': 0 }
stdlib_exec_functions¶
stdlib_exec_functions
Mapping from execution function names to the index of the string parameter.Type: dict[bauhaus.analysis.config.QualifiedName, int]
Default:
{ '_execl': 0, '_execle': 0, '_execlp': 0, '_execlpe': 0, '_execv': 0, '_execve': 0, '_execvp': 0, '_execvpe': 0, '_popen': 0, '_spawnl': 1, '_spawnle': 1, '_spawnlp': 1, '_spawnlpe': 1, '_spawnv': 1, '_spawnve': 1, '_spawnvp': 1, '_spawnvpe': 1, 'execl': 0, 'execle': 0, 'execlp': 0, 'execlpe': 0, 'execv': 0, 'execve': 0, 'execvp': 0, 'execvpe': 0, 'spawnl': 1, 'spawnle': 1, 'spawnlp': 1, 'spawnlpe': 1, 'spawnv': 1, 'spawnve': 1, 'spawnvp': 1, 'spawnvpe': 1, 'system': 0 }
stdlib_file_functions¶
stdlib_file_functions
Mapping from file function names to the index of the string parameter.Type: dict[bauhaus.analysis.config.QualifiedName, int]
Default:
{ '_access': 0, '_access_s': 0, '_chdir': 0, '_chmod': 0, '_creat': 0, '_findfirst': 0, '_findfirst32': 0, '_findfirst32i64': 0, '_findfirst64': 0, '_findfirst64i32': 0, '_findfirsti64': 0, '_fsopen': 0, '_fullpath': 0, '_fullpath_dbg': 0, '_getcwd': 0, '_getcwd_dbg': 0, '_getdcwd': 1, '_getdcwd_dbg': 1, '_getdcwd_nolock': 1, '_makepath': 0, '_makepath_s': 0, '_mkdir': 0, '_mktemp': 0, '_mktemp_s': 0, '_open': 0, '_remove': 0, '_rename': 0, '_rmdir': 0, '_sopen': 0, '_sopen_s': 1, '_splitpath': 0, '_splitpath_s': 0, '_stat': 0, '_stat32': 0, '_stat32i64': 0, '_stat64': 0, '_stat64i32': 0, '_stati64': 0, '_tempnam': 0, '_tempnam_dbg': 0, '_unlink': 0, '_utime': 0, '_utime32': 0, '_utime64': 0, 'access': 0, 'chdir': 0, 'chmod': 0, 'creat': 0, 'fopen': 0, 'fopen_s': 1, 'freopen': 0, 'freopen_s': 0, 'getcwd': 0, 'mkdir': 0, 'mktemp': 0, 'open': 0, 'remove': 0, 'rename': 0, 'rmdir': 0, 'sopen': 0, 'stat': 0, 'std::basic_filebuf::basic_filebuf': 1, 'std::basic_filebuf::open': 1, 'std::basic_fstream::basic_fstream': 1, 'std::basic_fstream::open': 1, 'std::basic_ifstream::basic_ifstream': 1, 'std::basic_ifstream::open': 1, 'std::basic_ofstream::basic_ofstream': 1, 'std::basic_ofstream::open': 1, 'std::experimental::filesystem::path::append': 1, 'std::experimental::filesystem::path::assign': 1, 'std::experimental::filesystem::path::concat': 1, 'std::experimental::filesystem::path::generic_string': -1, 'std::experimental::filesystem::path::operator+=': 1, 'std::experimental::filesystem::path::operator/=': 1, 'std::experimental::filesystem::path::operator=': 1, 'std::experimental::filesystem::path::path': 1, 'std::experimental::filesystem::path::string': -1, 'std::filesystem::path::append': 1, 'std::filesystem::path::assign': 1, 'std::filesystem::path::concat': 1, 'std::filesystem::path::generic_string': -1, 'std::filesystem::path::operator+=': 1, 'std::filesystem::path::operator/=': 1, 'std::filesystem::path::operator=': 1, 'std::filesystem::path::path': 1, 'std::filesystem::path::string': -1, 'tempnam': 0, 'tmpnam_s': 0, 'unlink': 0, 'utime': 0 }
stdlib_time_functions¶
stdlib_time_functions
Mapping from time function names to the index of the string parameter.Type: dict[bauhaus.analysis.config.QualifiedName, int]
Default:
{ '_ctime32': -1, '_ctime32_s': 0, '_ctime64': -1, '_ctime64_s': 0, '_strdate': 0, '_strdate_s': 0, '_strftime_l': 0, '_strtime': 0, '_strtime_s': 0, 'ctime': -1, 'ctime_s': 0, 'strftime': 0 }