Skip to content

Commit 95a54f7

Browse files
authored
Merge pull request github#10938 from geoffw0/printfprecision
C++: Fix printf.qll bug
2 parents 4ca0838 + 22cdeec commit 95a54f7

File tree

12 files changed

+282
-18
lines changed

12 files changed

+282
-18
lines changed
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
---
2+
category: minorAnalysis
3+
---
4+
* Fixed bugs in the `FormatLiteral` class that were causing `getMaxConvertedLength` and related predicates to return no results when the format literal was `%e`, `%f` or `%g` and an explicit precision was specified.

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

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1125,12 +1125,12 @@ class FormatLiteral extends Literal {
11251125
exists(int dot, int afterdot |
11261126
(if this.getPrecision(n) = 0 then dot = 0 else dot = 1) and
11271127
(
1128-
(
1129-
if this.hasExplicitPrecision(n)
1130-
then afterdot = this.getPrecision(n)
1131-
else not this.hasImplicitPrecision(n)
1132-
) and
1133-
afterdot = 6
1128+
if this.hasExplicitPrecision(n)
1129+
then afterdot = this.getPrecision(n)
1130+
else (
1131+
not this.hasImplicitPrecision(n) and
1132+
afterdot = 6
1133+
)
11341134
) and
11351135
len = 1 + 309 + dot + afterdot
11361136
) and
@@ -1140,12 +1140,12 @@ class FormatLiteral extends Literal {
11401140
exists(int dot, int afterdot |
11411141
(if this.getPrecision(n) = 0 then dot = 0 else dot = 1) and
11421142
(
1143-
(
1144-
if this.hasExplicitPrecision(n)
1145-
then afterdot = this.getPrecision(n)
1146-
else not this.hasImplicitPrecision(n)
1147-
) and
1148-
afterdot = 6
1143+
if this.hasExplicitPrecision(n)
1144+
then afterdot = this.getPrecision(n)
1145+
else (
1146+
not this.hasImplicitPrecision(n) and
1147+
afterdot = 6
1148+
)
11491149
) and
11501150
len = 1 + 1 + dot + afterdot + 1 + 1 + 3
11511151
) and
@@ -1155,12 +1155,12 @@ class FormatLiteral extends Literal {
11551155
exists(int dot, int afterdot |
11561156
(if this.getPrecision(n) = 0 then dot = 0 else dot = 1) and
11571157
(
1158-
(
1159-
if this.hasExplicitPrecision(n)
1160-
then afterdot = this.getPrecision(n)
1161-
else not this.hasImplicitPrecision(n)
1162-
) and
1163-
afterdot = 6
1158+
if this.hasExplicitPrecision(n)
1159+
then afterdot = this.getPrecision(n)
1160+
else (
1161+
not this.hasImplicitPrecision(n) and
1162+
afterdot = 6
1163+
)
11641164
) and
11651165
// note: this could be displayed in the style %e or %f;
11661166
// however %f is only used when 'P > X >= -4'
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
2+
typedef void *va_list;
3+
4+
int myPrintf(const char *format, ...) __attribute__((format(printf, 1, 2)));
5+
int mySprintf(char *buffer, const char *format, ...) __attribute__((format(__printf__, 2, 3)));
6+
int myVprintf(const char *format, va_list arg) __attribute__((format(printf, 1, 0)));
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
| AttributeFormattingFunction.cpp:4:5:4:12 | myPrintf | 0 | char | wchar_t | wchar_t |
2+
| AttributeFormattingFunction.cpp:5:5:5:13 | mySprintf | 1 | char | wchar_t | wchar_t |
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
import cpp
2+
3+
from AttributeFormattingFunction f
4+
select f, f.getFormatParameterIndex(), concat(f.getDefaultCharType().toString(), ", "),
5+
concat(f.getWideCharType().toString(), ", "), concat(f.getNonDefaultCharType().toString(), ", ")
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
| AttributeFormattingFunction.cpp:4:54:4:59 | format | printf | 0 | 1 |
2+
| AttributeFormattingFunction.cpp:5:69:5:74 | format | __printf__ | 1 | 2 |
3+
| AttributeFormattingFunction.cpp:6:63:6:68 | format | printf | 0 | |
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
import cpp
2+
3+
from FormatAttribute fa
4+
select fa, fa.getArchetype(), concat(fa.getFormatIndex().toString(), ", "),
5+
concat(fa.getFirstFormatArgIndex().toString(), ", ")
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
| test.c:14:9:14:10 | | 1 |
2+
| test.c:15:9:15:14 | | 2 |
3+
| test.c:16:9:16:12 | \t | 2 |
4+
| test.c:17:9:17:12 | %% | 2 |
5+
| test.c:20:9:20:12 | %c | 2 |
6+
| test.c:21:9:21:16 | %c%c%c | 4 |
7+
| test.c:24:9:24:23 | Hello, world! | 14 |
8+
| test.c:25:9:25:12 | %s | 14 |
9+
| test.c:26:9:26:14 | %.4s | 5 |
10+
| test.c:27:9:27:16 | %s, %s | 14 |
11+
| test.c:30:9:30:12 | %i | 12 |
12+
| test.c:31:9:31:14 | %lli | 12 |
13+
| test.c:32:9:32:12 | %i | 12 |
14+
| test.c:33:9:33:14 | %lli | 21 |
15+
| test.c:34:9:34:12 | %d | 12 |
16+
| test.c:35:9:35:12 | %u | 11 |
17+
| test.c:36:9:36:12 | %x | 9 |
18+
| test.c:37:9:37:12 | %X | 9 |
19+
| test.c:38:9:38:13 | %#x | 11 |
20+
| test.c:39:9:39:12 | %o | 12 |
21+
| test.c:40:9:40:13 | %#o | 13 |
22+
| test.c:43:9:43:12 | %f | 318 |
23+
| test.c:44:9:44:14 | %.2f | 314 |
24+
| test.c:45:9:45:12 | %e | 15 |
25+
| test.c:59:10:59:14 | %Ii | 12 |
26+
| test.c:66:10:66:14 | %zu | 21 |
27+
| test.c:67:10:67:14 | %Zu | 21 |
28+
| test.c:74:10:74:14 | %lc | 2 |
29+
| test.c:78:9:78:20 | %2$i, %1$i | 5 |
30+
| test.c:79:9:79:20 | %2$i, %1$i | 25 |
31+
| test.c:81:9:81:24 | %2$02i %1$4.2f | |
32+
| test.c:85:10:85:18 | %2$*1$d | |
33+
| test.c:86:10:86:19 | %2$0*1$d | |
34+
| test.c:92:10:92:19 | %2$.*1$f | |
35+
| test.c:99:10:99:12 | # | 2 |
36+
| test.c:100:10:100:13 | %% | 2 |
37+
| test.c:101:10:101:15 | %%%% | 3 |
38+
| test.c:102:10:102:15 | %%%f | 319 |
39+
| test.c:103:10:103:17 | %%%%%f | 320 |
40+
| test.c:104:10:104:18 | %4.2f%% | 315 |
41+
| test.c:105:10:105:17 | %%%f%% | 320 |
42+
| test.c:112:10:112:13 | %f | 318 |
43+
| test.c:113:10:113:15 | %.1f | 313 |
44+
| test.c:114:10:114:14 | %1f | 318 |
45+
| test.c:115:10:115:16 | %1.1f | 313 |
46+
| test.c:116:10:116:13 | %e | 15 |
47+
| test.c:117:10:117:15 | %.2e | 11 |
48+
| test.c:118:10:118:14 | %3e | 15 |
49+
| test.c:119:10:119:16 | %3.2e | 11 |
50+
| test.c:120:10:120:13 | %g | 15 |
51+
| test.c:121:10:121:15 | %.1g | 10 |
52+
| test.c:122:10:122:14 | %4g | 15 |
53+
| test.c:123:10:123:16 | %4.1g | 10 |
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
import semmle.code.cpp.commons.Printf
2+
3+
from FormatLiteral fl
4+
select fl, concat(fl.getMaxConvertedLength().toString(), ", ")
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
| test.c:20:9:20:12 | %c | 0 | | c | | file://:0:0:0:0 | char |
2+
| test.c:21:9:21:16 | %c%c%c | 0 | | c | | file://:0:0:0:0 | char |
3+
| test.c:21:9:21:16 | %c%c%c | 1 | | c | | file://:0:0:0:0 | char |
4+
| test.c:21:9:21:16 | %c%c%c | 2 | | c | | file://:0:0:0:0 | char |
5+
| test.c:25:9:25:12 | %s | 0 | | s | | file://:0:0:0:0 | char * |
6+
| test.c:26:9:26:14 | %.4s | 0 | | s | | file://:0:0:0:0 | char * |
7+
| test.c:27:9:27:16 | %s, %s | 0 | | s | | file://:0:0:0:0 | char * |
8+
| test.c:27:9:27:16 | %s, %s | 1 | | s | | file://:0:0:0:0 | char * |
9+
| test.c:30:9:30:12 | %i | 0 | | i | | file://:0:0:0:0 | int |
10+
| test.c:31:9:31:14 | %lli | 0 | | i | ll | file://:0:0:0:0 | long long |
11+
| test.c:32:9:32:12 | %i | 0 | | i | | file://:0:0:0:0 | int |
12+
| test.c:33:9:33:14 | %lli | 0 | | i | ll | file://:0:0:0:0 | long long |
13+
| test.c:34:9:34:12 | %d | 0 | | d | | file://:0:0:0:0 | int |
14+
| test.c:35:9:35:12 | %u | 0 | | u | | file://:0:0:0:0 | unsigned int |
15+
| test.c:36:9:36:12 | %x | 0 | | x | | file://:0:0:0:0 | unsigned int |
16+
| test.c:37:9:37:12 | %X | 0 | | X | | file://:0:0:0:0 | unsigned int |
17+
| test.c:38:9:38:13 | %#x | 0 | | x | | file://:0:0:0:0 | unsigned int |
18+
| test.c:39:9:39:12 | %o | 0 | | o | | file://:0:0:0:0 | unsigned int |
19+
| test.c:40:9:40:13 | %#o | 0 | | o | | file://:0:0:0:0 | unsigned int |
20+
| test.c:43:9:43:12 | %f | 0 | | f | | file://:0:0:0:0 | double |
21+
| test.c:44:9:44:14 | %.2f | 0 | | f | | file://:0:0:0:0 | double |
22+
| test.c:45:9:45:12 | %e | 0 | | e | | file://:0:0:0:0 | double |
23+
| test.c:59:10:59:14 | %Ii | 0 | | i | | file://:0:0:0:0 | int |
24+
| test.c:66:10:66:14 | %zu | 0 | | u | z | test.c:50:27:50:32 | size_t |
25+
| test.c:67:10:67:14 | %Zu | 0 | | u | Z | test.c:50:27:50:32 | size_t |
26+
| test.c:74:10:74:14 | %lc | 0 | | c | l | file://:0:0:0:0 | wchar_t |
27+
| test.c:78:9:78:20 | %2$i, %1$i | 0 | 2$ | i | | file://:0:0:0:0 | int |
28+
| test.c:78:9:78:20 | %2$i, %1$i | 1 | 1$ | i | | file://:0:0:0:0 | int |
29+
| test.c:79:9:79:20 | %2$i, %1$i | 0 | 2$ | i | | file://:0:0:0:0 | int |
30+
| test.c:79:9:79:20 | %2$i, %1$i | 1 | 1$ | i | | file://:0:0:0:0 | int |
31+
| test.c:81:9:81:24 | %2$02i %1$4.2f | 0 | 2$ | i | | file://:0:0:0:0 | int |
32+
| test.c:81:9:81:24 | %2$02i %1$4.2f | 1 | 1$ | f | | file://:0:0:0:0 | double |
33+
| test.c:85:10:85:18 | %2$*1$d | 0 | 2$ | d | | file://:0:0:0:0 | int |
34+
| test.c:86:10:86:19 | %2$0*1$d | 0 | 2$ | d | | file://:0:0:0:0 | int |
35+
| test.c:92:10:92:19 | %2$.*1$f | 0 | 2$ | f | | file://:0:0:0:0 | double |
36+
| test.c:102:10:102:15 | %%%f | 0 | | f | | file://:0:0:0:0 | double |
37+
| test.c:103:10:103:17 | %%%%%f | 0 | | f | | file://:0:0:0:0 | double |
38+
| test.c:104:10:104:18 | %4.2f%% | 0 | | f | | file://:0:0:0:0 | double |
39+
| test.c:105:10:105:17 | %%%f%% | 0 | | f | | file://:0:0:0:0 | double |
40+
| test.c:112:10:112:13 | %f | 0 | | f | | file://:0:0:0:0 | double |
41+
| test.c:113:10:113:15 | %.1f | 0 | | f | | file://:0:0:0:0 | double |
42+
| test.c:114:10:114:14 | %1f | 0 | | f | | file://:0:0:0:0 | double |
43+
| test.c:115:10:115:16 | %1.1f | 0 | | f | | file://:0:0:0:0 | double |
44+
| test.c:116:10:116:13 | %e | 0 | | e | | file://:0:0:0:0 | double |
45+
| test.c:117:10:117:15 | %.2e | 0 | | e | | file://:0:0:0:0 | double |
46+
| test.c:118:10:118:14 | %3e | 0 | | e | | file://:0:0:0:0 | double |
47+
| test.c:119:10:119:16 | %3.2e | 0 | | e | | file://:0:0:0:0 | double |
48+
| test.c:120:10:120:13 | %g | 0 | | g | | file://:0:0:0:0 | double |
49+
| test.c:121:10:121:15 | %.1g | 0 | | g | | file://:0:0:0:0 | double |
50+
| test.c:122:10:122:14 | %4g | 0 | | g | | file://:0:0:0:0 | double |
51+
| test.c:123:10:123:16 | %4.1g | 0 | | g | | file://:0:0:0:0 | double |

0 commit comments

Comments
 (0)