Skip to content

Commit 4720c5a

Browse files
authored
Merge pull request #264 from raulgarciamsft/users/raulga/c6276
C++: incorrect string type conversion
2 parents 03f2d8f + 3873cbd commit 4720c5a

File tree

6 files changed

+107
-0
lines changed

6 files changed

+107
-0
lines changed
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
wchar_t* pSrc;
2+
3+
pSrc = (wchar_t*)"a"; // casting a byte-string literal "a" to a wide-character string
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
<!DOCTYPE qhelp PUBLIC
2+
"-//Semmle//qhelp//EN"
3+
"qhelp.dtd">
4+
<qhelp>
5+
6+
<overview>
7+
<p>This rule indicates a potentially incorrect cast from an byte string (<code>char *</code>) to a wide-character string (<code>wchar_t *</code>).</p>
8+
<p>This cast might yield strings that are not correctly terminated; including potential buffer overruns when using such strings with some dangerous APIs.</p>
9+
</overview>
10+
11+
<recommendation>
12+
<p>Do not explicitly cast byte strings to wide-character strings.</p>
13+
<p>For string literals, prepend the literal string with the letter "L" to indicate that the string is a wide-character string (<code>wchar_t *</code>).</p>
14+
<p>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.</p>
15+
</recommendation>
16+
17+
<example>
18+
<p>In the following example, an byte string literal (<code>"a"</code>) is cast to a wide-character string.</p>
19+
<sample src="WcharCharConversion.cpp" />
20+
21+
<p>To fix this issue, prepend the literal with the letter "L" (<code>L"a"</code>) to define it as a wide-character string.</p>
22+
</example>
23+
24+
<references>
25+
<li>
26+
General resources:
27+
<a href="https://en.cppreference.com/w/cpp/string/multibyte/mbstowcs">std::mbstowcs</a>
28+
</li>
29+
<li>
30+
Microsoft specific resources:
31+
<a href="https://docs.microsoft.com/en-us/windows/desktop/Intl/security-considerations--international-features">Security Considerations: International Features</a>
32+
</li>
33+
</references>
34+
35+
</qhelp>
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
/**
2+
* @name Cast from char* to wchar_t*
3+
* @description Casting a byte string to a wide-character string is likely
4+
* to yield a string that is incorrectly terminated or aligned.
5+
* This can lead to undefined behavior, including buffer overruns.
6+
* @kind problem
7+
* @id cpp/incorrect-string-type-conversion
8+
* @problem.severity error
9+
* @precision high
10+
* @tags security
11+
* external/cwe/cwe-704
12+
* external/microsoft/c/c6276
13+
*/
14+
import cpp
15+
16+
class WideCharPointerType extends PointerType {
17+
WideCharPointerType() {
18+
this.getBaseType() instanceof WideCharType
19+
}
20+
}
21+
22+
from Expr e1, Cast e2
23+
where
24+
e2 = e1.getConversion() and
25+
exists(WideCharPointerType w, CharPointerType c |
26+
w = e2.getType().getUnspecifiedType().(PointerType) and
27+
c = e1.getType().getUnspecifiedType().(PointerType)
28+
)
29+
select e1, "Conversion from " + e1.getType().toString() + " to " + e2.getType().toString() + ". Use of invalid string can lead to undefined behavior."
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
#define NULL 0
2+
#define CONST const
3+
typedef wchar_t WCHAR; // wc, 16-bit UNICODE character
4+
typedef char CHAR;
5+
6+
typedef WCHAR *LPWSTR;
7+
typedef CONST WCHAR *LPCWSTR;
8+
9+
typedef CHAR *LPSTR;
10+
typedef CONST CHAR *LPCSTR;
11+
12+
void fconstWChar(LPCWSTR p) {}
13+
void fWChar(LPWSTR p) {}
14+
15+
void Test()
16+
{
17+
char *lpChar = NULL;
18+
wchar_t *lpWchar = NULL;
19+
LPCSTR lpcstr = "b";
20+
21+
lpWchar = (LPWSTR)"a"; // BUG
22+
lpWchar = (LPWSTR)lpcstr; // BUG
23+
24+
lpWchar = (wchar_t*)lpChar; // BUG
25+
26+
fconstWChar((LPCWSTR)lpChar); // BUG
27+
fWChar((LPWSTR)lpChar); // BUG
28+
29+
lpChar = (LPSTR)"a"; // Valid
30+
lpWchar = (LPWSTR)L"a"; // Valid
31+
32+
fconstWChar((LPCWSTR)lpWchar); // Valid
33+
fWChar(lpWchar); // Valid
34+
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
| WcharCharConversion.cpp:21:20:21:22 | array to pointer conversion | Conversion from const char * to LPWSTR. Use of invalid string can lead to undefined behavior. |
2+
| WcharCharConversion.cpp:22:20:22:25 | lpcstr | Conversion from LPCSTR to LPWSTR. Use of invalid string can lead to undefined behavior. |
3+
| WcharCharConversion.cpp:24:22:24:27 | lpChar | Conversion from char * to wchar_t *. Use of invalid string can lead to undefined behavior. |
4+
| WcharCharConversion.cpp:26:23:26:28 | lpChar | Conversion from char * to LPCWSTR. Use of invalid string can lead to undefined behavior. |
5+
| WcharCharConversion.cpp:27:17:27:22 | lpChar | Conversion from char * to LPWSTR. Use of invalid string can lead to undefined behavior. |
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Security/CWE/CWE-704/WcharCharConversion.ql

0 commit comments

Comments
 (0)