Semmle 1.20
Skip to end of metadata
Go to start of metadata

Name: Cast from char* to wchar_t*

Description: Casting a byte string to a wide-character string is likely to yield a string that is incorrectly terminated or aligned. This can lead to undefined behavior, including buffer overruns.

ID: cpp/incorrect-string-type-conversion

Kind: problem

Severity: error

Precision: high

Query: WcharCharConversion.ql
/**
 * @name Cast from char* to wchar_t*
 * @description Casting a byte string to a wide-character string is likely 
 *              to yield a string that is incorrectly terminated or aligned. 
 *              This can lead to undefined behavior, including buffer overruns.
 * @kind problem
 * @id cpp/incorrect-string-type-conversion
 * @problem.severity error
 * @precision high
 * @tags security
 *       external/cwe/cwe-704
 *       external/microsoft/c/c6276
 */
import cpp

class WideCharPointerType extends PointerType {
  WideCharPointerType() { 
    this.getBaseType() instanceof WideCharType 
  }
}

from Expr e1, Cast e2
where 
  e2 = e1.getConversion() and
  exists(WideCharPointerType w, CharPointerType c |
    w = e2.getType().getUnspecifiedType().(PointerType) and
    c = e1.getType().getUnspecifiedType().(PointerType)
  )
select e1, "Conversion from " + e1.getType().toString() + " to " +  e2.getType().toString() + ". Use of invalid string can lead to undefined behavior."

This rule indicates a potentially incorrect cast from an byte string (char *) to a wide-character string (wchar_t *).

This cast might yield strings that are not correctly terminated; including potential buffer overruns when using such strings with some dangerous APIs.

Recommendation

Do not explicitly cast byte strings to wide-character strings.

For string literals, prepend the literal string with the letter "L" to indicate that the string is a wide-character string (wchar_t *).

For converting a byte literal to a wide-character string literal, you would need to use the appropriate conversion function for the platform you are using. Please see the references section for options according to your platform.

Example

In the following example, an byte string literal ("a") is cast to a wide-character string.

wchar_t* pSrc;

pSrc = (wchar_t*)"a"; // casting a byte-string literal "a" to a wide-character string

To fix this issue, prepend the literal with the letter "L" (L"a") to define it as a wide-character string.

References