You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
The standard library provides locks to help control concurrent access to resources during their lifetime. When you declare a lock object without a name, the compiler creates a temporary object that's immediately destructed rather than one that lives to the end of the enclosing scope. So, failure to assign a lock object to a variable is a mistake that effectively disables the locking mechanism (because temporary variables are transient). This rule tries to catch simple cases of such unintended behavior.
18
+
The standard library provides locks to help control concurrent access to resources during their lifetime. When you declare a lock object without a name, the compiler creates a temporary object that's immediately destructed rather than one that lives to the end of the enclosing scope. So, failure to assign a lock object to a variable is a mistake that effectively disables the locking mechanism (because temporary variables are transient). This rule catches simple cases of such unintended behavior.
19
19
20
-
This diagnostic only analyzes the standard lock types `std::scoped_lock`, `std::unique_lock`, and `std::lock_guard`. Other unnamed RAII types are covered by [C26444](c26444.md).
20
+
This diagnostic only analyzes the standard lock types `std::scoped_lock`, `std::unique_lock`, and `std::lock_guard`. Warning [C26444](c26444.md) covers other unnamed RAII types.
21
21
22
-
Only simple calls to constructors are analyzed. More complex initializer expressions may lead to inaccurate results, but it's an unusual scenario. Locks passed as arguments to function calls or returned as results of function calls are ignored. To provide similar protection for types returned by a function call, annotate them with `[[nodiscard]]`. Locks created as temporaries but assigned to named references to extend their lifetime are ignored.
22
+
The analyzer only analyzes simple calls to constructors. More complex initializer expressions may lead to missed warnings. For example, the analyzer can't tell whether a temporary guard used as a function call argument deliberately only protects that function call or is a mistake by the user. The analyzer ignores locks passed as arguments to function calls or returned as results of function calls. To provide similar protection for types returned by a function call, annotate them with `[[nodiscard]]`. The analyzer also ignores locks created as temporaries but assigned to named references to extend their lifetime.
23
23
24
24
Code analysis name: `NO_UNNAMED_GUARDS`
25
25
26
26
## Example
27
27
28
-
This example is missing the name of the scoped lock.
28
+
In this example the name of the scoped lock is missing.
`_Use_decl_annotations_` tells the compiler to use the annotations from an earlier declaration of the function. If no earlier declaration can be found, or if the current declaration makes changes to the annotations, then this warning is emitted. `_Use_decl_annotations_` also lets you remove all other annotations from the definition, and uses the declaration annotations for analysis of the function.
14
+
`_Use_decl_annotations_` tells the compiler to use the annotations from an earlier declaration of the function. If it can't find an earlier declaration, or if the current declaration makes changes to the annotations, it emits this warning. `_Use_decl_annotations_` also lets you remove all other annotations from the definition, and uses the declaration annotations for analysis of the function.
15
15
16
-
This diagnostic is frequently a side effect of refactoring or fixing other warnings by adjusting the annotations on a function. To fix the issue, use the same annotations at the other locations. To determine the correct set of annotations, look at the behavior in the function definition. In most cases, this behavior is intentional and should be reflected in the annotations to the function. For more information on SAL annotations, see [Using SAL Annotations to reduce code defects](using-sal-annotations-to-reduce-c-cpp-code-defects.md).
16
+
This diagnostic is frequently a side effect of refactoring or fixing other warnings by adjusting the annotations on a function. To fix the issue, use the same annotations at the other locations. To determine the correct set of annotations, look at the behavior in the function definition. In most cases, this behavior is intentional and the annotations to the function should reflect it. For more information on SAL annotations, see [Using SAL Annotations to reduce code defects](using-sal-annotations-to-reduce-c-cpp-code-defects.md).
17
17
18
-
It's important for the annotations to match between the declarations and the definition of a function. When the analysis tools analyze the call site of the function, the declaration annotations are used. If the declaration and definition don't match, the static analysis tools may produce incorrect results. When you fix this warning, it's common for your changes to have cascading effects as the tool reanalyzes the source with updated information.
18
+
It's important for the annotations to match between the declarations and the definition of a function. When the analysis tools analyze the call site of the function, they use the declaration annotations. If the declaration and definition don't match, the static analysis tools may produce incorrect results. When you fix this warning, it's common for your changes to have cascading effects as the tool reanalyzes the source with updated information.
19
19
20
-
If this diagnostic occurs because no previous declaration was found in the translation unit, the most likely cause is a missing `#include` directive. To resolve this issue when the header file is intentionally not included, verify that the annotations in the declaration and definition match, and remove the `_Use_decl_annotations_` annotation. Be careful when you don't include a header file, as the two sets of annotations may get out of sync in the future.
20
+
If this diagnostic occurs because the analyzer couldn't find a previous declaration in the translation unit, the most likely cause is a missing `#include` directive. To resolve this issue when you intentionally don't include the header file, verify that the annotations in the declaration and definition match, and remove the `_Use_decl_annotations_` annotation. Be careful when you don't include a header file, as the two sets of annotations may get out of sync in the future.
21
21
22
22
Code analysis name: `BAD_USEHEADER`
23
23
@@ -41,15 +41,15 @@ void addNullTerminate(_Out_writes_z_(n) char* buffer, int n)
41
41
}
42
42
```
43
43
44
-
Examine the function definition to determine what the correct annotations should be. In this case, `_Out_writes_z_(n)` appears to be correct so we move that annotation to the function declaration in the header file. This resolves the issue because the annotations in the declaration and definition now match.
44
+
Examine the function definition to determine what the correct annotations should be. In this case, `_Out_writes_z_(n)` appears to be correct, so we move that annotation to the function declaration in the header file. This change resolves the issue because the annotations in the declaration and definition now match.
45
45
46
46
*From example.h:*
47
47
48
48
```cpp
49
49
voidaddNullTerminate(_Out_writes_z_(n) char* buffer, int n);
50
50
```
51
51
52
-
The buffer annotation on the definition can now be removed to simplify future maintenance (although this step is optional).
52
+
Now we can remove the buffer annotation on the definition to simplify future maintenance (although this step is optional).
53
53
54
54
*From example.cpp:*
55
55
@@ -63,7 +63,6 @@ void addNullTerminate(char* buffer, int n)
63
63
64
64
In real world code, it's not usually as clear which annotation is correct. For more information and guidance, see [using SAL Annotations to reduce code defects](using-sal-annotations-to-reduce-c-cpp-code-defects.md).
65
65
66
-
67
66
## See also
68
67
69
68
[Rule sets for C++ code](./using-rule-sets-to-specify-the-cpp-rules-to-run.md)\
Copy file name to clipboardExpand all lines: docs/code-quality/c6029.md
+4-4Lines changed: 4 additions & 4 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -13,13 +13,13 @@ Possible buffer overrun in called function due to an unchecked buffer length/siz
13
13
14
14
## Remarks
15
15
16
-
This warning indicates a function that takes a buffer and a size is passed an unchecked size. The data read-in from some external source hasn't been verified to see whether it's smaller than the buffer size. An attacker might intentionally specify a value far larger than expected for the size, which can lead to a buffer overrun. Generally, whenever you read data from an untrusted external source, make sure to verify it for validity. It's appropriate to verify the size to make sure it's in the expected range.
16
+
This warning indicates that code passes an unchecked size to a function that takes a buffer and a size. The code doesn't verify that the data read from some external source is smaller than the buffer size. An attacker might intentionally specify a larger than expected value for the size, which can lead to a buffer overrun. Generally, whenever you read data from an untrusted external source, make sure to verify it for validity. It's appropriate to verify the size to make sure it's in the expected range.
17
17
18
18
Code analysis name: `USING_TAINTED_DATA`
19
19
20
20
## Example
21
21
22
-
The following code generates this warning by calling the annotated function `std::fread` two times. The first call is used to determine the length of the data to read in later calls. After the first call, analysis marks `dataSize` as coming from an untrusted source. Therefore, passing the untrusted value to the second `std::fread` callgenerates this warning. A malicious actor would be able to modify the file and cause the call to `std::fread` to overflow the `buffer` array. In real world code, you should also handle error recovery based on the return value of `std::fread`. For simplicity, error recovery is intentionally left out of these examples.
22
+
The following code generates this warning when it calls the annotated function `std::fread` two times. The code uses the first call to determine the length of the data to read in later calls. After the first call, analysis marks `dataSize` as coming from an untrusted source. Therefore, when the code passes the untrusted value to the second `std::fread` call, the analyzer generates this warning. A malicious actor could modify the file and cause the call to `std::fread` to overflow the `buffer` array. In real world code, you should also handle error recovery based on the return value of `std::fread`. For simplicity, these examples intentionally leave out error recovery code.
23
23
24
24
```cpp
25
25
voidprocessData(FILE* file)
@@ -35,7 +35,7 @@ void processData(FILE* file)
35
35
}
36
36
```
37
37
38
-
The fix for the issue depends on the nature of the data and the behavior of the annotated function that is triggering the diagnostic. For more information, see the documentation for that function. A straightforward fix is to check the size before the second call to `std:fread`. In the next example, we throw an exception to terminate the function. Most real-world code would instead have an error recovery strategy that is specific to the scenario.
38
+
The fix for the issue depends on the nature of the data and the behavior of the annotated function that triggers the diagnostic. For more information, see the documentation for that function. A straightforward fix is to check the size before the second call to `std:fread`. In the next example, we throw an exception to terminate the function. Most real-world code would instead have an error recovery strategy that's specific to the scenario.
39
39
40
40
```cpp
41
41
void processData(FILE* file)
@@ -55,7 +55,7 @@ void processData(FILE* file)
55
55
}
56
56
```
57
57
58
-
In `std:fread` and similar functions, the code may need to read large amounts of data. To handle large data, you can allocate the size of the buffer dynamically after the size becomes known. Or, you can call `std:fread` multiple times as needed to read in the rest of the data. If you allocate the buffer dynamically, consider limiting the size to avoid introducing an out-of-memory exploit for large values. We don't use this approach in our example because it's already bounded by the size of `uint8_t`.
58
+
In `std:fread` and similar functions, the code may need to read large amounts of data. To handle large data, you can allocate the size of the buffer dynamically after the size becomes known. Or, you can call `std:fread` multiple times as needed to read in the rest of the data. If you allocate the buffer dynamically, we recommend you put a limit on the size to avoid introducing an out-of-memory exploit for large values. We don't use this approach in our example because it's already bounded by the size of `uint8_t`.
The following code generates this warning because an incorrect number of arguments were used in the call to `sprintf_s` and the missing argument was an integer. If the unsafe function `sprintf` was used instead of the safer variant `sprintf_s`, this code would likely cause a stack overflow instead of just an unexpected output:
22
+
The following code generates this warning because it uses an incorrect number of arguments in the call to `sprintf_s` and the missing argument is an integer. If the unsafe function `sprintf` was used instead of the safer variant `sprintf_s`, this code would likely cause a stack overflow instead of just an unexpected output:
Copy file name to clipboardExpand all lines: docs/code-quality/c6101.md
+5-5Lines changed: 5 additions & 5 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -13,23 +13,23 @@ A successful path through the function doesn't set the `_Out_` annotated paramet
13
13
14
14
## Remarks
15
15
16
-
The purpose of this warning is to avoid the use of uninitialized values by callers of the function. The analyzer assumes all parameters annotated with `_Out_`are uninitialized before the function call, and checks that they're initialized by it. This warning isn't emitted if the function returns a value indicating it had an error or wasn't successful. To fix this issue, make sure the `_Out_` parameter is initialized under all successful return paths. The error message contains the line numbers of an example path that doesn't initialize the parameter.
16
+
The purpose of this warning is to avoid the use of uninitialized values by callers of the function. The analyzer assumes callers don't initialize any parameters annotated with `_Out_` before the function call, and checks that the function initializes them. The analyzer doesn't emit this warning if the function returns a value that indicates it had an error or wasn't successful. To fix this issue, make sure to initialize the `_Out_` parameter under all successful return paths. The error message contains the line numbers of an example path that doesn't initialize the parameter.
17
17
18
-
If the initialization behavior is by design, then the warning is likely caused by incorrect or missing SAL annotations. You can typically resolve these cases by either changing `_Out_` to a more appropriate annotation, or by using the `_Success_()` annotation to help define the success/error states of the function. Having correct annotations on the function is important for the static analysis tools when analyzing the call sites of the function.
18
+
If the initialization behavior is by design, then incorrect or missing SAL annotations are a likely cause for the warning. You can typically resolve these cases in one of two ways: Either change `_Out_` to a more appropriate annotation, or use the `_Success_()` annotation to help define the success/error states of the function. It's important for the static analysis tools to have correct annotations on the function when analyzing the call sites of the function.
19
19
20
20
### Fix by changes to parameter annotations
21
21
22
-
If the parameter is expected to already be in an initialized state and the function conditionally modifies it, then the `_Inout_` annotation may be more appropriate. Another option is to use lower level annotations such as `_Pre_null_`, `_Pre_satisfies_()`, and `_Post_satisfies_()` that provide extra flexibility and control over the expected state of the parameter. For more information on parameter annotations, see [Annotating function parameters and return values](./annotating-function-parameters-and-return-values.md).
22
+
If the parameter should already be in an initialized state and the function conditionally modifies it, then the `_Inout_` annotation may be more appropriate. Another option is to use lower level annotations such as `_Pre_null_`, `_Pre_satisfies_()`, and `_Post_satisfies_()` that provide extra flexibility and control over the expected state of the parameter. For more information on parameter annotations, see [Annotating function parameters and return values](./annotating-function-parameters-and-return-values.md).
23
23
24
24
### Fix by defining successful return paths
25
25
26
-
This diagnostic is only emitted when the `_Out_` parameter isn't initialized in the success paths of the function. If there's no `_Success_` annotation and the return type for the function isn't annotated, then all return paths are considered successful. For more information on `_Success_` and similar annotations, see [Success/Failure annotations](./annotating-function-behavior.md#successfailure-annotations).
26
+
The analyzer only emits this warning when the code doesn't initialize an `_Out_` parameter in the success paths of the function. If there's no `_Success_` annotation and no function return type annotation, then it considers all return paths successful. For more information on `_Success_` and similar annotations, see [Success/Failure annotations](./annotating-function-behavior.md#successfailure-annotations).
27
27
28
28
Code analysis name: `RETURN_UNINIT_VAR`
29
29
30
30
## Example
31
31
32
-
The following code generates this warning. Because the function returns void, all paths are considered successful. In this case, the correct fix would probably be to adjust the logic of the `if` statement, but in real world code it's typically not as straightforward and depends on the intended behavior of the function.
32
+
The following code generates this warning. Because the function returns `void`, the analyzer considers all paths successful. In this case, the correct fix would probably be to adjust the logic of the `if` statement, but in real world code it's typically not as straightforward and the solution depends on the intended behavior of the function.
0 commit comments