Main Content

CWE Rule 176

Improper Handling of Unicode Encoding

Since R2026a

Description

Improper Handling of Unicode Encoding

Polyspace Implementation

The rule checker checks for these issues:

  • Buffer cannot hold as many characters as specified

  • Misuse of narrow or wide character string

Examples

expand all

Issue

This issue occurs when one of the Windows® API functions for character encoding conversions, MultiByteToWideChar or WideCharToMultiByte, is called with an insufficient buffer size.

Risk

A buffer overflow can occur if the buffer size in MultiByteToWideChar or WideCharToMultiByte cannot hold as many characters as specified.

Fix

One possible fix is to ensure that the functions receive a sufficient output buffer size, specified in the correct units:

  • WideCharToMultiByte expects the output buffer size in bytes.

  • MultiByteToWideChar expects the output buffer size in wide characters.

If you do not want to fix the issue, add comments to your result or code. For more information, see:

Example — MultiByteToWideChar Buffer Too Small

          
          
          #include <windows.h>
#include <lm.h>

void getUserInfo(char *username, LPBYTE* info) {
  WCHAR unicodeUser[UNLEN+1];
  MultiByteToWideChar(0, 0, username, -1, unicodeUser, sizeof(unicodeUser)); // Noncompliant
  NetUserGetInfo(NULL, unicodeUser, 2, info);
}

In this example, the function uses sizeof(unicodeUser) to calculate the buffer size, which gives the size in bytes instead of the required number of wide characters. This can lead to buffer overflow.

Correction — Calculate Buffer Size in Wide Characters

One possible correction is to replace sizeof(unicodeUser) with UNLEN+1, which ensures there is enough space in the buffer to store the longest possible user name plus the required null-terminator. This ensures the string is properly terminated and prevents buffer overflow.


          
          
          #include <windows.h>
#include <lm.h>

void getUserInfo(char *username, LPBYTE* info) {
  WCHAR unicodeUser[UNLEN+1];
  MultiByteToWideChar(0, 0, username, -1, unicodeUser, UNLEN+1); // Compliant
  NetUserGetInfo(NULL, unicodeUser, 2, info);
}
Issue

This issue occurs when you pass a narrow character string to a wide string function, or a wide character string to a narrow string function. If narrow and wide character strings have the same size on your operating system, Polyspace® does not report a violation.

Risk

Using a narrow character string with a wide string function, or vice versa, can result in unexpected or undefined behavior.

If you pass a wide character string to a narrow string function, you can encounter these issues:

  • Data truncation — If the string contains null bytes, a copy operation using strncpy() can terminate early.

  • Incorrect string length — strlen() returns the number of characters of a string up to the first null byte. A wide string can have additional characters after its first null byte.

If you pass a narrow character string to a wide string function, you can encounter this issue:

  • Buffer overflow — In a copy operation using wcsncpy(), the destination string might have insufficient memory to store the result of the copy.

Fix

Use the narrow string functions with narrow character strings. Use the wide string functions with wide character strings.

Example — Passing Wide Character Strings to strncpy()

          #include <string.h>
#include <wchar.h>

void func(void)
{
    wchar_t wide_str1[]  = L"0123456789";
    wchar_t wide_str2[] =  L"0000000000";
    strncpy((char *)wide_str2, (const char *)wide_str1, 10); // Noncompliant
}

In this example, strncpy() copies 10 wide characters from wide_strt1 to wide_str2. If wide_str1 contains null bytes, the copy operation can end prematurely and truncate the wide character string.

Correction — Use wcsncpy() to Copy Wide Character Strings

One possible correction is to use wcsncpy() to copy wide_str1 to wide_str2.


          #include <string.h>
#include <wchar.h>

void func(void)
{
    wchar_t wide_str1[]  = L"0123456789";
    wchar_t wide_str2[] =  L"0000000000";
    wcsncpy(wide_str2, wide_str1, 10); // Compliant
}

Check Information

Category: Others
PQL Name: std.cwe_native.R176

Version History

Introduced in R2026a