Skip to content

Commit 2841897

Browse files
committed
CPP: Make getAFormatterWideType more general and move it into FormattingFunction.qll.
1 parent 580471a commit 2841897

File tree

5 files changed

+25
-30
lines changed

5 files changed

+25
-30
lines changed

cpp/ql/src/semmle/code/cpp/commons/Printf.qll

Lines changed: 0 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -28,25 +28,6 @@ class AttributeFormattingFunction extends FormattingFunction {
2828
}
2929
}
3030

31-
/**
32-
* A type that is used as a format string by a wide variadic formatter such as
33-
* `vwprintf` or by a user-defined formatting function with the GNU `format`
34-
* attribute.
35-
*/
36-
Type getAFormatterWideType() {
37-
exists(TopLevelFunction f, int formatParamIndex |
38-
primitiveVariadicFormatter(f, formatParamIndex, true) and
39-
result = f.getParameter(formatParamIndex).getType().getUnspecifiedType() and
40-
result.(PointerType).getBaseType().getSize() != 1 and
41-
f.hasDefinition()
42-
)
43-
or
44-
exists(AttributeFormattingFunction f, int formatParamIndex |
45-
result = f.getParameter(formatParamIndex).getType().getUnspecifiedType() and
46-
result.(PointerType).getBaseType().getSize() != 1
47-
)
48-
}
49-
5031
/**
5132
* A standard function such as `vprintf` that has a format parameter
5233
* and a variable argument list of type `va_arg`.

cpp/ql/src/semmle/code/cpp/models/interfaces/FormattingFunction.qll

Lines changed: 21 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,27 @@
77
*/
88

99
import semmle.code.cpp.Function
10+
11+
private Type stripTopLevelSpecifiersOnly(Type t) {
12+
(
13+
result = stripTopLevelSpecifiersOnly(t.(SpecifiedType).getBaseType())
14+
) or (
15+
result = t and
16+
not t instanceof SpecifiedType
17+
)
18+
}
19+
20+
/**
21+
* A type that is used as a format string by any formatting function.
22+
*/
23+
Type getAFormatterWideType() {
24+
exists(FormattingFunction ff, Type t |
25+
t = stripTopLevelSpecifiersOnly(ff.getDefaultCharType()) and
26+
t.getSize() != 1 and
27+
result.(PointerType).getBaseType() = t
28+
)
29+
}
30+
1031
/**
1132
* A type that is used as a format string by any formatting function, or `wchar_t` if
1233
* there is none.
@@ -19,15 +40,6 @@ private Type getAFormatterWideTypeOrDefault() {
1940
)
2041
}
2142

22-
private Type stripTopLevelSpecifiersOnly(Type t) {
23-
(
24-
result = stripTopLevelSpecifiersOnly(t.(SpecifiedType).getBaseType())
25-
) or (
26-
result = t and
27-
not t instanceof SpecifiedType
28-
)
29-
}
30-
3143
/**
3244
* A standard library function that uses a `printf`-like formatting string.
3345
*/

cpp/ql/test/query-tests/Likely Bugs/Format/WrongTypeFormatArguments/Linux_mixed_byte_wprintf/WrongTypeFormatArguments.expected

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
| tests.cpp:18:15:18:22 | Hello | This argument should be of type 'char *' but is of type 'char16_t *' |
22
| tests.cpp:19:15:19:22 | Hello | This argument should be of type 'char *' but is of type 'wchar_t *' |
3+
| tests.cpp:21:15:21:21 | Hello | This argument should be of type 'char16_t *' but is of type 'char *' |
34
| tests.cpp:21:15:21:21 | Hello | This argument should be of type 'wchar_t *' but is of type 'char *' |
45
| tests.cpp:22:15:22:22 | Hello | This argument should be of type 'wchar_t *' but is of type 'char16_t *' |
6+
| tests.cpp:23:15:23:22 | Hello | This argument should be of type 'char16_t *' but is of type 'wchar_t *' |
57
| tests.cpp:25:17:25:23 | Hello | This argument should be of type 'wchar_t *' but is of type 'char *' |
68
| tests.cpp:26:17:26:24 | Hello | This argument should be of type 'wchar_t *' but is of type 'char16_t *' |
79
| tests.cpp:30:17:30:24 | Hello | This argument should be of type 'char *' but is of type 'char16_t *' |
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
1-
| tests.cpp:8:5:8:10 | printf | char | wchar_t | wchar_t |
1+
| tests.cpp:8:5:8:10 | printf | char | char16_t, wchar_t | char16_t, wchar_t |
22
| tests.cpp:9:5:9:11 | wprintf | wchar_t | char | wchar_t |
33
| tests.cpp:10:5:10:12 | swprintf | char16_t | char | char16_t |

cpp/ql/test/query-tests/Likely Bugs/Format/WrongTypeFormatArguments/Linux_mixed_byte_wprintf/tests.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ void tests() {
2020

2121
printf("%S", "Hello"); // BAD: expecting wchar_t or char16_t
2222
printf("%S", u"Hello"); // GOOD [FALSE POSITIVE]
23-
printf("%S", L"Hello"); // GOOD
23+
printf("%S", L"Hello"); // GOOD [FALSE POSITIVE]
2424

2525
wprintf(L"%s", "Hello"); // BAD: expecting wchar_t
2626
wprintf(L"%s", u"Hello"); // BAD: expecting wchar_t

0 commit comments

Comments
 (0)