Skip to content

Commit 99286fb

Browse files
authored
Merge pull request github#11704 from jketema/scanf-free
C++: Exclude deallocation functions as `scanf` result accesses
2 parents d7e44a5 + ef61d14 commit 99286fb

File tree

4 files changed

+48
-20
lines changed

4 files changed

+48
-20
lines changed

cpp/ql/src/Critical/MissingCheckScanf.ql

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,8 @@ BasicBlock blockGuardedBy(int value, string op, ScanfFunctionCall call) {
115115
from ScanfOutput output, ScanfFunctionCall call, Access access
116116
where
117117
output.getCall() = call and
118-
output.hasGuardedAccess(access, false)
118+
output.hasGuardedAccess(access, false) and
119+
not exists(DeallocationExpr dealloc | dealloc.getFreedExpr() = access)
119120
select access,
120121
"This variable is read, but may not have been written. " +
121122
"It should be guarded by a check that the $@ returns at least " +
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
---
2+
category: minorAnalysis
3+
---
4+
* The `cpp/missing-check-scanf` query no longer reports the free'ing of `scanf` output variables as potential reads.
Lines changed: 21 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,21 @@
1-
| test.cpp:30:7:30:7 | i | This variable is read, but may not have been written. It should be guarded by a check that the $@ returns at least 1. | test.cpp:29:3:29:7 | call to scanf | call to scanf |
2-
| test.cpp:46:7:46:7 | i | This variable is read, but may not have been written. It should be guarded by a check that the $@ returns at least 1. | test.cpp:45:3:45:7 | call to scanf | call to scanf |
3-
| test.cpp:63:7:63:7 | i | This variable is read, but may not have been written. It should be guarded by a check that the $@ returns at least 1. | test.cpp:62:3:62:7 | call to scanf | call to scanf |
4-
| test.cpp:75:7:75:7 | i | This variable is read, but may not have been written. It should be guarded by a check that the $@ returns at least 1. | test.cpp:74:3:74:7 | call to scanf | call to scanf |
5-
| test.cpp:87:7:87:7 | i | This variable is read, but may not have been written. It should be guarded by a check that the $@ returns at least 1. | test.cpp:86:3:86:8 | call to fscanf | call to fscanf |
6-
| test.cpp:94:7:94:7 | i | This variable is read, but may not have been written. It should be guarded by a check that the $@ returns at least 1. | test.cpp:93:3:93:8 | call to sscanf | call to sscanf |
7-
| test.cpp:143:8:143:8 | i | This variable is read, but may not have been written. It should be guarded by a check that the $@ returns at least 1. | test.cpp:141:7:141:11 | call to scanf | call to scanf |
8-
| test.cpp:152:8:152:8 | i | This variable is read, but may not have been written. It should be guarded by a check that the $@ returns at least 1. | test.cpp:150:7:150:11 | call to scanf | call to scanf |
9-
| test.cpp:184:8:184:8 | i | This variable is read, but may not have been written. It should be guarded by a check that the $@ returns at least 1. | test.cpp:183:7:183:11 | call to scanf | call to scanf |
10-
| test.cpp:203:8:203:8 | j | This variable is read, but may not have been written. It should be guarded by a check that the $@ returns at least 2. | test.cpp:200:7:200:11 | call to scanf | call to scanf |
11-
| test.cpp:227:9:227:9 | d | This variable is read, but may not have been written. It should be guarded by a check that the $@ returns at least 2. | test.cpp:225:25:225:29 | call to scanf | call to scanf |
12-
| test.cpp:231:9:231:9 | d | This variable is read, but may not have been written. It should be guarded by a check that the $@ returns at least 2. | test.cpp:229:14:229:18 | call to scanf | call to scanf |
13-
| test.cpp:243:7:243:7 | i | This variable is read, but may not have been written. It should be guarded by a check that the $@ returns at least 1. | test.cpp:242:3:242:7 | call to scanf | call to scanf |
14-
| test.cpp:251:7:251:7 | i | This variable is read, but may not have been written. It should be guarded by a check that the $@ returns at least 1. | test.cpp:250:3:250:7 | call to scanf | call to scanf |
15-
| test.cpp:259:7:259:7 | i | This variable is read, but may not have been written. It should be guarded by a check that the $@ returns at least 1. | test.cpp:258:3:258:7 | call to scanf | call to scanf |
16-
| test.cpp:271:7:271:7 | i | This variable is read, but may not have been written. It should be guarded by a check that the $@ returns at least 1. | test.cpp:270:3:270:7 | call to scanf | call to scanf |
17-
| test.cpp:281:8:281:12 | ptr_i | This variable is read, but may not have been written. It should be guarded by a check that the $@ returns at least 1. | test.cpp:280:3:280:7 | call to scanf | call to scanf |
18-
| test.cpp:289:7:289:7 | i | This variable is read, but may not have been written. It should be guarded by a check that the $@ returns at least 1. | test.cpp:288:3:288:7 | call to scanf | call to scanf |
19-
| test.cpp:383:25:383:25 | u | This variable is read, but may not have been written. It should be guarded by a check that the $@ returns at least 1. | test.cpp:382:6:382:11 | call to sscanf | call to sscanf |
1+
| test.cpp:35:7:35:7 | i | This variable is read, but may not have been written. It should be guarded by a check that the $@ returns at least 1. | test.cpp:34:3:34:7 | call to scanf | call to scanf |
2+
| test.cpp:51:7:51:7 | i | This variable is read, but may not have been written. It should be guarded by a check that the $@ returns at least 1. | test.cpp:50:3:50:7 | call to scanf | call to scanf |
3+
| test.cpp:68:7:68:7 | i | This variable is read, but may not have been written. It should be guarded by a check that the $@ returns at least 1. | test.cpp:67:3:67:7 | call to scanf | call to scanf |
4+
| test.cpp:80:7:80:7 | i | This variable is read, but may not have been written. It should be guarded by a check that the $@ returns at least 1. | test.cpp:79:3:79:7 | call to scanf | call to scanf |
5+
| test.cpp:90:8:90:8 | i | This variable is read, but may not have been written. It should be guarded by a check that the $@ returns at least 1. | test.cpp:89:3:89:7 | call to scanf | call to scanf |
6+
| test.cpp:98:8:98:8 | i | This variable is read, but may not have been written. It should be guarded by a check that the $@ returns at least 1. | test.cpp:97:3:97:7 | call to scanf | call to scanf |
7+
| test.cpp:108:7:108:7 | i | This variable is read, but may not have been written. It should be guarded by a check that the $@ returns at least 1. | test.cpp:107:3:107:8 | call to fscanf | call to fscanf |
8+
| test.cpp:115:7:115:7 | i | This variable is read, but may not have been written. It should be guarded by a check that the $@ returns at least 1. | test.cpp:114:3:114:8 | call to sscanf | call to sscanf |
9+
| test.cpp:164:8:164:8 | i | This variable is read, but may not have been written. It should be guarded by a check that the $@ returns at least 1. | test.cpp:162:7:162:11 | call to scanf | call to scanf |
10+
| test.cpp:173:8:173:8 | i | This variable is read, but may not have been written. It should be guarded by a check that the $@ returns at least 1. | test.cpp:171:7:171:11 | call to scanf | call to scanf |
11+
| test.cpp:205:8:205:8 | i | This variable is read, but may not have been written. It should be guarded by a check that the $@ returns at least 1. | test.cpp:204:7:204:11 | call to scanf | call to scanf |
12+
| test.cpp:224:8:224:8 | j | This variable is read, but may not have been written. It should be guarded by a check that the $@ returns at least 2. | test.cpp:221:7:221:11 | call to scanf | call to scanf |
13+
| test.cpp:248:9:248:9 | d | This variable is read, but may not have been written. It should be guarded by a check that the $@ returns at least 2. | test.cpp:246:25:246:29 | call to scanf | call to scanf |
14+
| test.cpp:252:9:252:9 | d | This variable is read, but may not have been written. It should be guarded by a check that the $@ returns at least 2. | test.cpp:250:14:250:18 | call to scanf | call to scanf |
15+
| test.cpp:264:7:264:7 | i | This variable is read, but may not have been written. It should be guarded by a check that the $@ returns at least 1. | test.cpp:263:3:263:7 | call to scanf | call to scanf |
16+
| test.cpp:272:7:272:7 | i | This variable is read, but may not have been written. It should be guarded by a check that the $@ returns at least 1. | test.cpp:271:3:271:7 | call to scanf | call to scanf |
17+
| test.cpp:280:7:280:7 | i | This variable is read, but may not have been written. It should be guarded by a check that the $@ returns at least 1. | test.cpp:279:3:279:7 | call to scanf | call to scanf |
18+
| test.cpp:292:7:292:7 | i | This variable is read, but may not have been written. It should be guarded by a check that the $@ returns at least 1. | test.cpp:291:3:291:7 | call to scanf | call to scanf |
19+
| test.cpp:302:8:302:12 | ptr_i | This variable is read, but may not have been written. It should be guarded by a check that the $@ returns at least 1. | test.cpp:301:3:301:7 | call to scanf | call to scanf |
20+
| test.cpp:310:7:310:7 | i | This variable is read, but may not have been written. It should be guarded by a check that the $@ returns at least 1. | test.cpp:309:3:309:7 | call to scanf | call to scanf |
21+
| test.cpp:404:25:404:25 | u | This variable is read, but may not have been written. It should be guarded by a check that the $@ returns at least 1. | test.cpp:403:6:403:11 | call to sscanf | call to sscanf |

cpp/ql/test/query-tests/Critical/MissingCheckScanf/test.cpp

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,11 @@ FILE *get_a_stream();
1919
const char *get_a_string();
2020
extern locale_t get_a_locale();
2121

22+
typedef long size_t;
23+
24+
void *malloc(size_t size);
25+
void free(void *ptr);
26+
2227
int main()
2328
{
2429
// --- simple cases ---
@@ -78,6 +83,22 @@ int main()
7883
use(i); // GOOD
7984
}
8085

86+
{
87+
int *i = (int*)malloc(sizeof(int)); // Allocated variable
88+
89+
scanf("%d", i);
90+
use(*i); // BAD
91+
free(i); // GOOD
92+
}
93+
94+
{
95+
int *i = new int; // Allocated variable
96+
97+
scanf("%d", i);
98+
use(*i); // BAD
99+
delete i; // GOOD
100+
}
101+
81102
// --- different scanf functions ---
82103

83104
{

0 commit comments

Comments
 (0)