Skip to content

Commit 3905cf7

Browse files
authored
Merge pull request #1255 from geoffw0/wrongtypeformatmore
CPP: WrongTypeFormatArguments.ql Improvements
2 parents dcbf70f + 1ee28fa commit 3905cf7

File tree

18 files changed

+234
-14
lines changed

18 files changed

+234
-14
lines changed

cpp/ql/src/Likely Bugs/Format/WrongTypeFormatArguments.ql

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,7 @@ private predicate formattingFunctionCallExpectedType(FormattingFunctionCall ffc,
2525
ffc.getTarget() = f and
2626
f.getFormatParameterIndex() = i and
2727
ffc.getArgument(i) = fl and
28-
fl.getConversionType(pos) = expected and
29-
count(fl.getConversionType(pos)) = 1
28+
fl.getConversionType(pos) = expected
3029
)
3130
}
3231

@@ -143,7 +142,10 @@ from FormattingFunctionCall ffc, int n, Expr arg, Type expected, Type actual
143142
where (
144143
(
145144
formatArgType(ffc, n, expected, arg, actual) and
146-
not trivialConversion(expected.getUnspecifiedType(), actual.getUnspecifiedType())
145+
not exists(Type anyExpected |
146+
formatArgType(ffc, n, anyExpected, arg, actual) and
147+
trivialConversion(anyExpected.getUnspecifiedType(), actual.getUnspecifiedType())
148+
)
147149
)
148150
or
149151
(

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -578,7 +578,7 @@ class FormatLiteral extends Literal {
578578
or ((len="z" or len="Z")
579579
and (result = this.getSize_t() or result = this.getSsize_t()))
580580
or (len="t" and result = this.getPtrdiff_t())
581-
or (len="I" and result instanceof IntType)
581+
or (len="I" and (result = this.getSize_t() or result = this.getPtrdiff_t()))
582582
or (len="I32" and exists(MicrosoftInt32Type t |
583583
t.getUnsigned() = result.(IntegralType).getUnsigned()
584584
))
@@ -604,7 +604,7 @@ class FormatLiteral extends Literal {
604604
or ((len="z" or len="Z")
605605
and (result = this.getSize_t() or result = this.getSsize_t()))
606606
or (len="t" and result = this.getPtrdiff_t())
607-
or (len="I" and result instanceof IntType)
607+
or (len="I" and (result = this.getSize_t() or result = this.getPtrdiff_t()))
608608
or (len="I32" and exists(MicrosoftInt32Type t |
609609
t.getUnsigned() = result.(IntegralType).getUnsigned()
610610
))

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,5 +1,7 @@
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 *' |
4+
| tests.cpp:21:15:21:21 | Hello | This argument should be of type 'wchar_t *' but is of type 'char *' |
35
| tests.cpp:26:17:26:24 | Hello | This argument should be of type 'char *' but is of type 'char16_t *' |
46
| tests.cpp:27:17:27:24 | Hello | This argument should be of type 'char *' but is of type 'wchar_t *' |
57
| tests.cpp:29:17:29:23 | Hello | This argument should be of type 'wchar_t *' but is of type 'char *' |

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
@@ -18,7 +18,7 @@ void tests() {
1818
printf("%s", u"Hello"); // BAD: expecting char
1919
printf("%s", L"Hello"); // BAD: expecting char
2020

21-
printf("%S", "Hello"); // BAD: expecting wchar_t or char16_t [NOT DETECTED]
21+
printf("%S", "Hello"); // BAD: expecting wchar_t or char16_t
2222
printf("%S", u"Hello"); // GOOD
2323
printf("%S", L"Hello"); // GOOD
2424

Original file line numberDiff line numberDiff line change
@@ -1,2 +1,4 @@
11
| tests_32.cpp:14:16:14:23 | void_ptr | This argument should be of type 'long' but is of type 'void *' |
2+
| tests_32.cpp:15:15:15:15 | l | This argument should be of type 'void *' but is of type 'long' |
23
| tests_64.cpp:14:16:14:23 | void_ptr | This argument should be of type 'long' but is of type 'void *' |
4+
| tests_64.cpp:15:15:15:15 | l | This argument should be of type 'void *' but is of type 'long' |

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,6 @@ void test_32()
1212

1313
printf("%li", l); // GOOD
1414
printf("%li", void_ptr); // BAD
15-
printf("%p", l); // BAD [NOT DETECTED]
15+
printf("%p", l); // BAD
1616
printf("%p", void_ptr); // GOOD
1717
}

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,6 @@ void test_64()
1212

1313
printf("%li", l); // GOOD
1414
printf("%li", void_ptr); // BAD
15-
printf("%p", l); // BAD [NOT DETECTED]
15+
printf("%p", l); // BAD
1616
printf("%p", void_ptr); // GOOD
1717
}

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

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
| format.h:16:59:16:61 | str | This argument should be of type 'int' but is of type 'char *' |
22
| format.h:16:64:16:64 | i | This argument should be of type 'double' but is of type 'int' |
33
| format.h:16:67:16:67 | d | This argument should be of type 'char *' but is of type 'double' |
4+
| linux_c.c:11:15:11:18 | str3 | This argument should be of type 'char *' but is of type 'short *' |
45
| pri_macros.h:15:35:15:40 | my_u64 | This argument should be of type 'unsigned int' but is of type 'unsigned long long' |
56
| printf1.h:12:27:12:27 | i | This argument should be of type 'double' but is of type 'int' |
67
| printf1.h:18:18:18:18 | i | This argument should be of type 'void *' but is of type 'int' |
@@ -12,6 +13,8 @@
1213
| printf1.h:46:18:46:20 | ull | This argument should be of type 'unsigned int' but is of type 'unsigned long long' |
1314
| printf1.h:113:17:113:17 | d | This argument should be of type 'long double' but is of type 'double' |
1415
| printf1.h:114:18:114:18 | d | This argument should be of type 'long double' but is of type 'double' |
16+
| printf1.h:147:19:147:19 | i | This argument should be of type 'long long' but is of type 'int' |
17+
| printf1.h:148:19:148:20 | ui | This argument should be of type 'unsigned long long' but is of type 'unsigned int' |
1518
| real_world.h:61:21:61:22 | & ... | This argument should be of type 'int *' but is of type 'short *' |
1619
| real_world.h:62:22:62:23 | & ... | This argument should be of type 'short *' but is of type 'int *' |
1720
| real_world.h:63:22:63:24 | & ... | This argument should be of type 'short *' but is of type 'unsigned int *' |
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
/** standard printf functions */
2+
3+
int printf(const char *format, ...);
4+
5+
/** test program */
6+
7+
void restrict_cases(char * restrict str1, const char * restrict str2, short * restrict str3)
8+
{
9+
printf("%s", str1); // GOOD
10+
printf("%s", str2); // GOOD
11+
printf("%s", str3); // BAD
12+
}
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
semmle-extractor-options: --edg --signed_chars
1+
semmle-extractor-options: --clang --edg --signed_chars

0 commit comments

Comments
 (0)