Skip to content

Commit d4c931c

Browse files
committed
CPP: Permit %Ld and similar.
1 parent b3fd7ab commit d4c931c

File tree

9 files changed

+15
-25
lines changed

9 files changed

+15
-25
lines changed

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

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -572,9 +572,8 @@ class FormatLiteral extends Literal {
572572
((len="hh" and result instanceof IntType)
573573
or (len="h" and result instanceof IntType)
574574
or (len="l" and result = this.getLongType())
575-
or ((len="ll" or len="q")
575+
or ((len="ll" or len="L" or len="q")
576576
and result instanceof LongLongType)
577-
or (len="L" and result instanceof IntType) // doesn't affect integral conversion
578577
or (len="j" and result = this.getIntmax_t())
579578
or ((len="z" or len="Z")
580579
and (result = this.getSize_t() or result = this.getSsize_t()))
@@ -599,9 +598,8 @@ class FormatLiteral extends Literal {
599598
((len="hh" and result instanceof CharType)
600599
or (len="h" and result instanceof ShortType)
601600
or (len="l" and result = this.getLongType())
602-
or ((len="ll" or len="q")
601+
or ((len="ll" or len="L" or len="q")
603602
and result instanceof LongLongType)
604-
or (len="L" and result instanceof IntType) // doesn't affect integral conversion
605603
or (len="j" and result = this.getIntmax_t())
606604
or ((len="z" or len="Z")
607605
and (result = this.getSize_t() or result = this.getSsize_t()))
@@ -622,7 +620,7 @@ class FormatLiteral extends Literal {
622620
*/
623621
FloatingPointType getFloatingPointConversion(int n) {
624622
exists(string len | len = this.getLength(n) and
625-
if len="L" then
623+
if (len="L" or len="ll") then
626624
result instanceof LongDoubleType
627625
else
628626
result instanceof DoubleType)
@@ -638,7 +636,7 @@ class FormatLiteral extends Literal {
638636
(len="hh" and base instanceof CharType)
639637
or (len="h" and base instanceof ShortType)
640638
or (len="l" and base = this.getLongType())
641-
or (len="ll" and base instanceof LongLongType)
639+
or ((len="ll" or len="L") and base instanceof LongLongType)
642640
or (len="q" and base instanceof LongLongType)
643641
)
644642
and base.isSigned() and base = result.getBaseType()

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

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,8 @@
1010
| printf1.h:44:18:44:20 | ull | This argument should be of type 'int' but is of type 'unsigned long long' |
1111
| printf1.h:45:18:45:20 | ull | This argument should be of type 'unsigned int' but is of type 'unsigned long long' |
1212
| printf1.h:46:18:46:20 | ull | This argument should be of type 'unsigned int' but is of type 'unsigned long long' |
13-
| printf1.h:47:19:47:21 | ull | This argument should be of type 'unsigned int' but is of type 'unsigned long long' |
14-
| printf1.h:112:18:112:19 | ld | This argument should be of type 'double' but is of type 'long double' |
1513
| printf1.h:113:17:113:17 | d | This argument should be of type 'long double' but is of type 'double' |
16-
| printf1.h:122:17:122:19 | lli | This argument should be of type 'int' but is of type 'long long' |
17-
| printf1.h:123:17:123:18 | li | This argument should be of type 'int' but is of type 'long' |
18-
| printf1.h:132:17:132:20 | ulli | This argument should be of type 'unsigned int' but is of type 'unsigned long long' |
19-
| printf1.h:133:17:133:19 | uli | This argument should be of type 'unsigned int' but is of type 'unsigned long' |
14+
| printf1.h:114:18:114:18 | d | This argument should be of type 'long double' but is of type 'double' |
2015
| real_world.h:61:21:61:22 | & ... | This argument should be of type 'int *' but is of type 'short *' |
2116
| real_world.h:62:22:62:23 | & ... | This argument should be of type 'short *' but is of type 'int *' |
2217
| real_world.h:63:22:63:24 | & ... | This argument should be of type 'short *' but is of type 'unsigned int *' |

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

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ void f(char *s, int i, unsigned char *us, const char *cs, signed char *ss, char
4444
printf("%d", ull); // not ok (unsigned long long -> int)
4545
printf("%u", ull); // not ok (unsigned long long -> unsigned int)
4646
printf("%x", ull); // not ok (unsigned long long -> unsigned int)
47-
printf("%Lx", ull); // not ok (unsigned long long -> unsigned int)
47+
printf("%Lx", ull); // ok
4848
printf("%llx", ull); // ok
4949
}
5050

@@ -109,18 +109,18 @@ void extensions()
109109
double d;
110110

111111
printf("%Lg", ld); // GOOD
112-
printf("%llg", ld); // GOOD (nonstandard equivalent to %Lg) [FALSE POSITIVE]
112+
printf("%llg", ld); // GOOD (nonstandard equivalent to %Lg)
113113
printf("%Lg", d); // BAD (should be %g)
114-
printf("%llg", d); // BAD (should be %g) [NOT DETECTED]
114+
printf("%llg", d); // BAD (should be %g)
115115
}
116116

117117
{
118118
long long int lli;
119119
long int li;
120120

121121
printf("%lld", lli); // GOOD
122-
printf("%Ld", lli); // GOOD (nonstandard equivalent to %lld) [FALSE POSITIVE]
123-
printf("%Ld", li); // BAD (should be %ld)
122+
printf("%Ld", lli); // GOOD (nonstandard equivalent to %lld)
123+
printf("%Ld", li); // BAD (should be %ld) [NOT DETECTED]
124124
printf("%lld", li); // BAD (should be %ld) [NOT DETECTED]
125125
}
126126

@@ -129,8 +129,8 @@ void extensions()
129129
unsigned long int uli;
130130

131131
printf("%llu", ulli); // GOOD
132-
printf("%Lu", ulli); // GOOD (nonstandard equivalent to %llu) [FALSE POSITIVE]
133-
printf("%Lu", uli); // BAD (should be %lu)
132+
printf("%Lu", ulli); // GOOD (nonstandard equivalent to %llu)
133+
printf("%Lu", uli); // BAD (should be %lu) [NOT DETECTED]
134134
printf("%llu", uli); // BAD (should be %lu) [NOT DETECTED]
135135
}
136136
}

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

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@
1010
| printf1.h:44:18:44:20 | ull | This argument should be of type 'int' but is of type 'unsigned long long' |
1111
| printf1.h:45:18:45:20 | ull | This argument should be of type 'unsigned int' but is of type 'unsigned long long' |
1212
| printf1.h:46:18:46:20 | ull | This argument should be of type 'unsigned int' but is of type 'unsigned long long' |
13-
| printf1.h:47:19:47:21 | ull | This argument should be of type 'unsigned int' but is of type 'unsigned long long' |
1413
| printf1.h:126:18:126:19 | wc | This argument should be of type 'char *' but is of type 'wchar_t *' |
1514
| printf1.h:127:18:127:18 | c | This argument should be of type 'wchar_t *' but is of type 'char *' |
1615
| real_world.h:61:21:61:22 | & ... | This argument should be of type 'int *' but is of type 'short *' |

cpp/ql/test/query-tests/Likely Bugs/Format/WrongTypeFormatArguments/Linux_unsigned_chars/printf1.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ void f(char *s, int i, unsigned char *us, const char *cs, signed char *ss, char
4444
printf("%d", ull); // not ok (unsigned long long -> int)
4545
printf("%u", ull); // not ok (unsigned long long -> unsigned int)
4646
printf("%x", ull); // not ok (unsigned long long -> unsigned int)
47-
printf("%Lx", ull); // not ok (unsigned long long -> unsigned int)
47+
printf("%Lx", ull); // ok
4848
printf("%llx", ull); // ok
4949
}
5050

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

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@
1010
| printf1.h:44:18:44:20 | ull | This argument should be of type 'int' but is of type 'unsigned long long' |
1111
| printf1.h:45:18:45:20 | ull | This argument should be of type 'unsigned int' but is of type 'unsigned long long' |
1212
| printf1.h:46:18:46:20 | ull | This argument should be of type 'unsigned int' but is of type 'unsigned long long' |
13-
| printf1.h:47:19:47:21 | ull | This argument should be of type 'unsigned int' but is of type 'unsigned long long' |
1413
| printf1.h:71:19:71:20 | st | This argument should be of type 'ssize_t' but is of type 'unsigned long long' |
1514
| printf1.h:72:19:72:20 | ST | This argument should be of type 'ssize_t' but is of type 'unsigned long long' |
1615
| printf1.h:73:19:73:22 | c_st | This argument should be of type 'ssize_t' but is of type 'unsigned long long' |

cpp/ql/test/query-tests/Likely Bugs/Format/WrongTypeFormatArguments/Microsoft/printf1.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ void f(char *s, int i, unsigned char *us, const char *cs, signed char *ss, char
4444
printf("%d", ull); // not ok (unsigned long long -> int)
4545
printf("%u", ull); // not ok (unsigned long long -> unsigned int)
4646
printf("%x", ull); // not ok (unsigned long long -> unsigned int)
47-
printf("%Lx", ull); // not ok (unsigned long long -> unsigned int)
47+
printf("%Lx", ull); // ok
4848
printf("%llx", ull); // ok
4949
}
5050

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

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@
1010
| printf1.h:44:18:44:20 | ull | This argument should be of type 'int' but is of type 'unsigned long long' |
1111
| printf1.h:45:18:45:20 | ull | This argument should be of type 'unsigned int' but is of type 'unsigned long long' |
1212
| printf1.h:46:18:46:20 | ull | This argument should be of type 'unsigned int' but is of type 'unsigned long long' |
13-
| printf1.h:47:19:47:21 | ull | This argument should be of type 'unsigned int' but is of type 'unsigned long long' |
1413
| printf1.h:71:19:71:20 | st | This argument should be of type 'ssize_t' but is of type 'unsigned long long' |
1514
| printf1.h:72:19:72:20 | ST | This argument should be of type 'ssize_t' but is of type 'unsigned long long' |
1615
| printf1.h:73:19:73:22 | c_st | This argument should be of type 'ssize_t' but is of type 'unsigned long long' |

cpp/ql/test/query-tests/Likely Bugs/Format/WrongTypeFormatArguments/Microsoft_no_wchar/printf1.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ void f(char *s, int i, unsigned char *us, const char *cs, signed char *ss, char
4444
printf("%d", ull); // not ok (unsigned long long -> int)
4545
printf("%u", ull); // not ok (unsigned long long -> unsigned int)
4646
printf("%x", ull); // not ok (unsigned long long -> unsigned int)
47-
printf("%Lx", ull); // not ok (unsigned long long -> unsigned int)
47+
printf("%Lx", ull); // ok
4848
printf("%llx", ull); // ok
4949
}
5050

0 commit comments

Comments
 (0)