Skip to content

Commit 253b8d1

Browse files
C++ : cpp/incorrect-string-type-conversion
Cast between semantically different string types: char* from/to wchar_t* NOTE: Please let me know if you want to use a different CWE than CWE-704
1 parent 54493eb commit 253b8d1

File tree

7 files changed

+116
-0
lines changed

7 files changed

+116
-0
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,3 +13,4 @@
1313
/.vs/ql/v15/Browse.VC.db
1414
/.vs/ProjectSettings.json
1515

16+
/.vs/ql/v15/.suo
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
LPWSTR pSrc;
2+
3+
pSrc = (LPWSTR)"a";
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
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/to an ANSI string (<code>char *</code>) to/from a Unicode 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 casting ANSI strings to/from Unicode strings.</p>
13+
</recommendation>
14+
15+
<example>
16+
<p>In the following example, an ANSI string literal (<code>"a"</code>) is casted as a Unicode string.</p>
17+
<sample src="WcharCharConversion.cpp" />
18+
19+
<p>To fix this issue, prepend the literal with the letter "L" (<code>L"a"</code>) to define it as a Unicode string.</p>
20+
</example>
21+
22+
<references>
23+
</references>
24+
25+
</qhelp>
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
/**
2+
* @name Cast between semantically different string types: char* from/to wchar_t*
3+
* @description This rule indicates a potentially incorrect cast from/to an ANSI string (char *) to/from a Unicode string (wchar_t *).
4+
* This cast might yield strings that are not correctly terminated;
5+
* including potential buffer overruns when using such strings with some dangerous APIs.
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()
25+
and
26+
(
27+
exists( WideCharPointerType w, CharPointerType c |
28+
w = e1.getType().getUnspecifiedType().(PointerType)
29+
and c = e2.getType().getUnspecifiedType().(PointerType)
30+
)
31+
or exists
32+
(
33+
WideCharPointerType w, CharPointerType c |
34+
w = e2.getType().getUnspecifiedType().(PointerType)
35+
and c = e1.getType().getUnspecifiedType().(PointerType)
36+
)
37+
)
38+
select e1, "Conversion from " + e1.getType().toString() + " to " + e2.getType().toString() + ". Use of invalid string can lead to undefined behavior."
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
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 fconstChar(LPCSTR p) {}
13+
void fChar(LPSTR p) {}
14+
void fconstWChar(LPCWSTR p) {}
15+
void fWChar(LPWSTR p) {}
16+
17+
void Test()
18+
{
19+
char *lpChar = NULL;
20+
wchar_t *lpWchar = NULL;
21+
22+
lpChar = (LPSTR)L"a"; // BUG
23+
lpWchar = (LPWSTR)"a"; // BUG
24+
25+
lpChar = (char*)lpWchar; // BUG
26+
lpWchar = (wchar_t*)lpChar; // BUG
27+
28+
fconstChar((LPCSTR)lpWchar); // BUG
29+
fChar((LPSTR)lpWchar); // BUG
30+
fconstWChar((LPCWSTR)lpChar); // BUG
31+
fWChar((LPWSTR)lpChar); // BUG
32+
33+
lpChar = (LPSTR)"a"; // Valid
34+
lpWchar = (LPWSTR)L"a"; // Valid
35+
36+
fconstChar((LPCSTR)lpChar); // Valid
37+
fChar(lpChar); // Valid
38+
fconstWChar((LPCWSTR)lpWchar); // Valid
39+
fWChar(lpWchar); // Valid
40+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
| WcharCharConversion.cpp:22:18:22:21 | array to pointer conversion | Conversion from const wchar_t * to LPSTR. Use of invalid string can lead to undefined behavior. |
2+
| WcharCharConversion.cpp:23:20:23:22 | array to pointer conversion | Conversion from const char * to LPWSTR. Use of invalid string can lead to undefined behavior. |
3+
| WcharCharConversion.cpp:25:18:25:24 | lpWchar | Conversion from wchar_t * to char *. Use of invalid string can lead to undefined behavior. |
4+
| WcharCharConversion.cpp:26:22:26:27 | lpChar | Conversion from char * to wchar_t *. Use of invalid string can lead to undefined behavior. |
5+
| WcharCharConversion.cpp:28:21:28:27 | lpWchar | Conversion from wchar_t * to LPCSTR. Use of invalid string can lead to undefined behavior. |
6+
| WcharCharConversion.cpp:29:15:29:21 | lpWchar | Conversion from wchar_t * to LPSTR. Use of invalid string can lead to undefined behavior. |
7+
| WcharCharConversion.cpp:30:23:30:28 | lpChar | Conversion from char * to LPCWSTR. Use of invalid string can lead to undefined behavior. |
8+
| WcharCharConversion.cpp:31:17:31: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)