Skip to content

Commit 1a2b4a3

Browse files
authored
Merge pull request #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

+1-1
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

-7
This file was deleted.

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

+10-9
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>
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+
}
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+
}
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+
}
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);
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

+1-1
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
}
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
}

cpp/ql/src/Security/CWE/CWE-732/DoNotCreateWorldWritable.qhelp

+3-2
Original file line numberDiff line numberDiff line change
@@ -29,10 +29,11 @@ so it is important that they cannot be controlled by an attacker.
2929
</p>
3030

3131
<p>
32-
The first example creates the default configuration file with the usual "default" Unix permissions, <code>0666</code>. This makes the
32+
The first example creates the default configuration file with the usual "default" Unix permissions, <code>0666</code>. This makes the
3333
file world-writable, so that an attacker could write in their own configuration that would be read by the program. The second example uses
3434
more restrictive permissions: a combination of the standard Unix constants <code>S_IWUSR</code> and <code>S_IRUSR</code> which means that
35-
only the current user will have read and write access to the file.
35+
only the current user will have read and write access to the file. The third example shows another way to create a file with more restrictive
36+
permissions if a <code>FILE *</code> stream pointer is required rather than a file descriptor.
3637
</p>
3738

3839
<sample src="DoNotCreateWorldWritable.c" />
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
1-
| tests.cpp:18:15:18:22 | Hello | This argument should be of type 'char *' but is of type 'char16_t *'. |
2-
| 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 *'. |
5-
| tests.cpp:26:17:26:24 | Hello | This argument should be of type 'char *' but is of type 'char16_t *'. |
6-
| tests.cpp:30:17:30:24 | Hello | This argument should be of type 'wchar_t *' but is of type 'char16_t *'. |
7-
| tests.cpp:35:36:35:43 | Hello | This argument should be of type 'char *' but is of type 'wchar_t *'. |
8-
| tests.cpp:39:36:39:43 | Hello | This argument should be of type 'char16_t *' but is of type 'wchar_t *'. |
9-
| tests.cpp:42:37:42:44 | Hello | This argument should be of type 'char *' but is of type 'char16_t *'. |
10-
| tests.cpp:43:37:43:44 | Hello | This argument should be of type 'char *' but is of type 'wchar_t *'. |
11-
| tests.cpp:45:37:45:43 | Hello | This argument should be of type 'char16_t *' but is of type 'char *'. |
12-
| tests.cpp:47:37:47:44 | Hello | This argument should be of type 'char16_t *' but is of type 'wchar_t *'. |
1+
| tests.cpp:18:15:18:22 | Hello | This format specifier for type 'char *' does not match the argument type 'char16_t *'. |
2+
| tests.cpp:19:15:19:22 | Hello | This format specifier for type 'char *' does not match the argument type 'wchar_t *'. |
3+
| tests.cpp:21:15:21:21 | Hello | This format specifier for type 'char16_t *' does not match the argument type 'char *'. |
4+
| tests.cpp:21:15:21:21 | Hello | This format specifier for type 'wchar_t *' does not match the argument type 'char *'. |
5+
| tests.cpp:26:17:26:24 | Hello | This format specifier for type 'char *' does not match the argument type 'char16_t *'. |
6+
| tests.cpp:30:17:30:24 | Hello | This format specifier for type 'wchar_t *' does not match the argument type 'char16_t *'. |
7+
| tests.cpp:35:36:35:43 | Hello | This format specifier for type 'char *' does not match the argument type 'wchar_t *'. |
8+
| tests.cpp:39:36:39:43 | Hello | This format specifier for type 'char16_t *' does not match the argument type 'wchar_t *'. |
9+
| tests.cpp:42:37:42:44 | Hello | This format specifier for type 'char *' does not match the argument type 'char16_t *'. |
10+
| tests.cpp:43:37:43:44 | Hello | This format specifier for type 'char *' does not match the argument type 'wchar_t *'. |
11+
| tests.cpp:45:37:45:43 | Hello | This format specifier for type 'char16_t *' does not match the argument type 'char *'. |
12+
| tests.cpp:47:37:47:44 | Hello | This format specifier for type 'char16_t *' does not match the argument type 'wchar_t *'. |
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
| 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'. |
3-
| 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'. |
1+
| tests_32.cpp:14:16:14:23 | void_ptr | This format specifier for type 'long' does not match the argument type 'void *'. |
2+
| tests_32.cpp:15:15:15:15 | l | This format specifier for type 'void *' does not match the argument type 'long'. |
3+
| tests_64.cpp:14:16:14:23 | void_ptr | This format specifier for type 'long' does not match the argument type 'void *'. |
4+
| tests_64.cpp:15:15:15:15 | l | This format specifier for type 'void *' does not match the argument type 'long'. |

0 commit comments

Comments
 (0)