Skip to content

Commit 3338349

Browse files
authored
Merge pull request #226 from elbiazo/bad_wchar
adding bad wchar query
2 parents 2ef6dd9 + def69e4 commit 3338349

File tree

6 files changed

+98
-0
lines changed

6 files changed

+98
-0
lines changed
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
// Query should catch invalidWchar1 and invalidWchar2 but not semiValidWchar and validWchar
2+
const WCHAR invalidWchar3[] = {
3+
L'C', L'P', L'R', L'O', L'G', L'R', L'A', L'M', L' ', L'1', L'.', L'0',
4+
'L\0'};
5+
6+
const WCHAR invalidWchar2[] = {
7+
L'C', L'P', L'R', L'O', L'G', L'R', L'A', L'M', L' ', L'1', L'.', L'0',
8+
'LZ'};
9+
10+
const WCHAR semiValidWchar[] = {
11+
L'C', L'P', L'R', L'O', L'G', L'R', L'A', L'M', L' ', L'1', L'.', L'0',
12+
L'L\0'};
13+
14+
const WCHAR validWchar[] = {
15+
L'C', L'P', L'R', L'O', L'G', L'R', L'A', L'M', L' ', L'1', L'.', L'0',
16+
L'\0'};
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
<!DOCTYPE qhelp PUBLIC "-//Semmle//qhelp//EN" "qhelp.dtd">
2+
<qhelp>
3+
<overview>
4+
<p>This rule finds wide character that is initialized wrong due to a typo.
5+
</p>
6+
</overview>
7+
<recommendation>
8+
<p>The wide character should be initialized with the L prefix. If L is accidentally included
9+
inside the character literal, it should be moved outside to be a prefix.
10+
</p>
11+
</recommendation>
12+
<example>
13+
<sample src="BadWchar.cpp" />
14+
</example>
15+
</qhelp>
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
/**
2+
* @id cpp/microsoft/public/typo/bad-wchar
3+
* @name Initialization of bad wide char
4+
* @description wchar_t should be initialized with L prefix but might be initialized inside single quote. E.g. 'L\0' instead of L'\0'
5+
* @kind problem
6+
* @problem.severity error
7+
* @precision high
8+
* @tags security
9+
*/
10+
11+
import cpp
12+
13+
/**
14+
* Check where wchar_t is initalized wrong.
15+
* E.g. wchar_t a = 'LZ' (bad) instead of L'Z' (good)
16+
*/
17+
predicate badWchar(CharLiteral cl) {
18+
cl.getActualType().hasName("wchar_t") and
19+
cl.getValueText().regexpMatch("'L.+'") // wchar_t getValueText() generally looks like L'Z' or 'L\0'. but if it is 'LZ' or 'L\0', this might be bad
20+
}
21+
22+
/**
23+
* when codeql can't figure out what underlying type it is, it will default to int. Scenarios unique_ptr, it seems to have hard time figuring out...
24+
* we can check for others like 'LZ' or 'LA' but you will get alot of false positive since there can be enum :int with 'LZ' field etc
25+
* E.g. unique_ptr<PWSTR>('L\0'). If codeql couldnt figureout what unique_ptr is pointing to it will set it int.
26+
*/
27+
predicate wcharNullOnNonWchar(CharLiteral cl) {
28+
cl.getValue().toInt() = 19456 // 19456 (0x4c00) is 'L\0'
29+
}
30+
31+
from CharLiteral cl, string msg
32+
where
33+
(
34+
wcharNullOnNonWchar(cl) or
35+
badWchar(cl)
36+
) and
37+
msg =
38+
" Varible of type wchar_t maybe have been initialized with a typo. " + cl.getValueText() +
39+
" should be L'" + cl.getValueText().substring(2, cl.getValueText().length())
40+
select cl, "$@: " + msg, cl, cl.getValueText()
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
| test.cpp:8:9:8:13 | 19456 | $@: Varible of type wchar_t maybe have been initialized with a typo. 'L\\0' should be L'\\0' | test.cpp:8:9:8:13 | 19456 | 'L\\0' |
2+
| test.cpp:12:9:12:12 | 19546 | $@: Varible of type wchar_t maybe have been initialized with a typo. 'LZ' should be L'Z' | test.cpp:12:9:12:12 | 19546 | 'LZ' |
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Microsoft/Likely Bugs/Likely Typos/BadWchar.ql
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
// Query should catch invalidWchar1 and invalidWchar2 in invalidWcharTest function but not semiValidWchar and validWchar in validWcharTest function
2+
typedef wchar_t WCHAR;
3+
4+
void invalidWcharTest()
5+
{
6+
const WCHAR invalidWchar3[] = {
7+
L'C', L'P', L'R', L'O', L'G', L'R', L'A', L'M', L' ', L'1', L'.', L'0',
8+
'L\0'}; // 'L\0' should be L'\0'
9+
10+
const WCHAR invalidWchar2[] = {
11+
L'C', L'P', L'R', L'O', L'G', L'R', L'A', L'M', L' ', L'1', L'.', L'0',
12+
'LZ'}; // 'LZ' should be L'Z'
13+
}
14+
15+
void validWcharTest()
16+
{
17+
const WCHAR semiValidWchar[] = {
18+
L'C', L'P', L'R', L'O', L'G', L'R', L'A', L'M', L' ', L'1', L'.', L'0',
19+
L'L\0'};
20+
21+
const WCHAR validWchar[] = {
22+
L'C', L'P', L'R', L'O', L'G', L'R', L'A', L'M', L' ', L'1', L'.', L'0',
23+
L'\0'};
24+
}

0 commit comments

Comments
 (0)