Skip to content

Commit 1a2b4a3

Browse files
authored
Merge pull request github#16939 from geoffw0/docsforautofix
C++: Assorted minor doc improvements
2 parents 24914ef + bf47574 commit 1a2b4a3

22 files changed

+330
-209
lines changed

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -172,5 +172,5 @@ where
172172
not arg.isFromUninstantiatedTemplate(_) and
173173
not actual.getUnspecifiedType() instanceof ErroneousType
174174
select arg,
175-
"This argument should be of type '" + expected.getName() + "' but is of type '" +
175+
"This format specifier for type '" + expected.getName() + "' does not match the argument type '" +
176176
actual.getUnspecifiedType().getName() + "'."

cpp/ql/src/Likely Bugs/Memory Management/ReturnStackAllocatedMemory.cpp

Lines changed: 0 additions & 7 deletions
This file was deleted.

cpp/ql/src/Likely Bugs/Memory Management/ReturnStackAllocatedMemory.qhelp

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5,22 +5,23 @@
55

66

77
<overview>
8-
<p>This rule finds return statements that return pointers to an object allocated on the stack.
9-
The lifetime of a stack allocated memory location only lasts until the function returns, and
10-
the contents of that memory become undefined after that. Clearly, using a pointer to stack
8+
<p>This rule finds return statements that return pointers to an object allocated on the stack.
9+
The lifetime of a stack allocated memory location only lasts until the function returns, and
10+
the contents of that memory become undefined after that. Clearly, using a pointer to stack
1111
memory after the function has already returned will have undefined results. </p>
1212

1313
</overview>
1414
<recommendation>
15-
<p>Use the functions of the <tt>malloc</tt> family to dynamically allocate memory on the heap for data that is used across function calls.</p>
15+
<p>Use the functions of the <tt>malloc</tt> family, or <tt>new</tt>, to dynamically allocate memory on the heap for data that is used across function calls.</p>
1616

1717
</recommendation>
18-
<example><sample src="ReturnStackAllocatedMemory.cpp" />
19-
20-
21-
22-
18+
<example>
19+
<p>The following example allocates an object on the stack and returns a pointer to it. This is incorrect because the object is deallocated
20+
when the function returns, and the pointer becomes invalid.</p>
21+
<sample src="ReturnStackAllocatedMemoryBad.cpp" />
2322

23+
<p>To fix this, allocate the object on the heap using <tt>new</tt> and return a pointer to the heap-allocated object.</p>
24+
<sample src="ReturnStackAllocatedMemoryGood.cpp" />
2425
</example>
2526

2627
<references>
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
Record *mkRecord(int value) {
2+
Record myRecord(value);
3+
4+
return &myRecord; // BAD: returns a pointer to `myRecord`, which is a stack-allocated object.
5+
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
Record *mkRecord(int value) {
2+
Record *myRecord = new Record(value);
3+
4+
return myRecord; // GOOD: returns a pointer to a `myRecord`, which is a heap-allocated object.
5+
}
Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,14 @@
1-
unsigned limit = get_limit();
2-
unsigned total = 0;
3-
while (limit - total > 0) { // wrong: if `total` is greater than `limit` this will underflow and continue executing the loop.
1+
uint32_t limit = get_limit();
2+
uint32_t total = 0;
3+
4+
while (limit - total > 0) { // BAD: if `total` is greater than `limit` this will underflow and continue executing the loop.
45
total += get_data();
5-
}
6+
}
7+
8+
while (total < limit) { // GOOD: never underflows here because there is no arithmetic.
9+
total += get_data();
10+
}
11+
12+
while ((int64_t)limit - total > 0) { // GOOD: never underflows here because the result always fits in an `int64_t`.
13+
total += get_data();
14+
}
Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,17 @@
11
char *file_name;
22
FILE *f_ptr;
3-
3+
44
/* Initialize file_name */
5-
5+
66
f_ptr = fopen(file_name, "w");
77
if (f_ptr == NULL) {
88
/* Handle error */
99
}
10-
10+
1111
/* ... */
12-
12+
1313
if (chmod(file_name, S_IRUSR) == -1) {
1414
/* Handle error */
15-
}
15+
}
16+
17+
fclose(f_ptr);
Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
char *file_name;
22
int fd;
3-
3+
44
/* Initialize file_name */
5-
5+
66
fd = open(
77
file_name,
88
O_WRONLY | O_CREAT | O_EXCL,
@@ -11,9 +11,11 @@ fd = open(
1111
if (fd == -1) {
1212
/* Handle error */
1313
}
14-
14+
1515
/* ... */
16-
16+
1717
if (fchmod(fd, S_IRUSR) == -1) {
1818
/* Handle error */
19-
}
19+
}
20+
21+
close(fd);

cpp/ql/src/Security/CWE/CWE-570/IncorrectAllocationErrorHandling.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ void good1(std::size_t length) noexcept {
3434

3535
// GOOD: the allocation failure is handled appropriately.
3636
void good2(std::size_t length) noexcept {
37-
int* dest = new int[length];
37+
int* dest = new(std::nothrow) int[length];
3838
if(!dest) {
3939
return;
4040
}
Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,38 @@
11
void write_default_config_bad() {
22
// BAD - this is world-writable so any user can overwrite the config
33
int out = creat(OUTFILE, 0666);
4-
dprintf(out, DEFAULT_CONFIG);
4+
if (out < 0) {
5+
// handle error
6+
}
7+
8+
dprintf(out, "%s", DEFAULT_CONFIG);
9+
close(out);
510
}
611

712
void write_default_config_good() {
813
// GOOD - this allows only the current user to modify the file
914
int out = creat(OUTFILE, S_IWUSR | S_IRUSR);
10-
dprintf(out, DEFAULT_CONFIG);
15+
if (out < 0) {
16+
// handle error
17+
}
18+
19+
dprintf(out, "%s", DEFAULT_CONFIG);
20+
close(out);
21+
}
22+
23+
void write_default_config_good_2() {
24+
// GOOD - this allows only the current user to modify the file
25+
int out = open(OUTFILE, O_WRONLY | O_CREAT, S_IWUSR | S_IRUSR);
26+
if (out < 0) {
27+
// handle error
28+
}
29+
30+
FILE *fd = fdopen(out, "w");
31+
if (fd == NULL) {
32+
close(out);
33+
// handle error
34+
}
35+
36+
fprintf(fd, "%s", DEFAULT_CONFIG);
37+
fclose(fd);
1138
}

0 commit comments

Comments
 (0)