11/16/2023 0 Comments Annotations examples![]() The expression return refers to a post-state value that isn't available in pre-state. _When_(return = 0, _Requires_lock_held_(p->cs)) In the following example, _Requires_lock_held_ is a precondition. Wrong context in _When_Īnother common mistake is to use post-state evaluation for preconditions. _Deref_out_range_(0, cbSize) isn't strictly required for some tools because it can be inferred from _Out_writes_to_(cbSize,*pcbFilled), but it's shown here for completeness. _Deref_out_range_(0, cbSize) _Out_ DWORD *pcbFilled _Out_writes_bytes_to_(cbSize, *pcbFilled) BYTE *pb, In the following example, the range of *pcbFilled is expressed, not pcbFilled. If the parameter is a pointer and you want to express the range of the value of the element that's pointed to by the pointer, use _Deref_out_range_ instead of _Out_range_. #include īOOL StrEquals1(_In_ PCHAR p1, _In_ PCHAR p2)īOOL StrEquals2(_In_ PSTR p1, _In_ PSTR p2) Use the appropriate STR version to replace the type, as shown in the following example. Missing the proper specification of null termination is common. ![]() Instead, what is probably intended is the specification of a null-terminated array to do that, use _In_ PWSTR. However, in most cases, this is probably not the specification that is intended. _In_ WCHAR* p says that there's an input pointer p that points to one character. It points to an input string that has null termination because the precondition of _In_ allows the recognition of a null-terminated string. Void Func2(_Out_writes_(n) PSTR wszFileName, size_t n) Īn annotation like _In_ PCSTR is common and useful. Void Func1(_Out_ PSTR pFileName, size_t n) This combination is interpreted as having an output parameter that points to a character buffer and the buffer is null-terminated. The use of _Out_ PSTR is almost always wrong. Void Func2(_Out_writes_all_(size) CHAR *pb, Void Func1(_Out_writes_to_(size, *pCount) CHAR *pb, The next example shows three correct ways to fully specify the exact size of the initialized portion of the buffer. However, it doesn't tell how many elements the function initializes. This annotation isn't strictly wrong and it's helpful to express the allocated size. It has cb bytes allocated, with the first byte initialized on exit. The annotation _Out_writes_ signifies that you have a buffer. ![]() The following example demonstrates a common misuse of _Out_writes_. A _Post_defensive_ annotation is also available, for use in callbacks where the trusted party is assumed to be the caller and the untrusted code is the called code. In that case, _In_ _Pre_defensive_ is preferred at a trust boundary to indicate that although a caller gets an error if it attempts to pass NULL, the function body is analyzed as if the parameter might be NULL, and any attempts to dereference the pointer without first checking it for NULL are flagged. The "defensive" modifier modifies certain annotations to indicate that, at the point of call, the interface should be checked strictly, but in the implementation body it should assume that incorrect parameters might be passed. If a function appears at a trust boundary, we recommend that you use the _Pre_defensive_ annotation. Although having a function check its parameter for unexpected NULL and return gracefully is a good defensive coding practice, it doesn't mean that the parameter annotation can be of an optional type ( _*Xxx*_opt_). This applies even to a function that checks its parameters and returns an error if it's NULL when it shouldn't be. If the caller isn't allowed to pass in a null pointer, use _In_ or _Out_ instead of _In_opt_ or _Out_opt_. If the function didn't check p1 for NULL, then _Out_opt_ because the function tolerates NULL as a valid argument, i.e. ![]() Be especially careful about the OPTIONAL comment macro because it's frequently placed incorrectly-for example, on the wrong side of a comma. Although we recommend that you convert these macros to SAL, we also urge you to be careful when you convert them because the code might have changed since the original prototype was written and the old macro might no longer reflect what the code does. Prior to SAL, many programmers used macros as comments-macros that were named IN, OUT, IN_OUT, or variants of these names. This is relevant in cases of automated conversion from older macros to SAL. If the function is supposed to write to the element, use _Inout_ instead of _In_. Here are some ways to get the most out of the Source Code Annotation Language (SAL) and avoid some common problems.
0 Comments
Leave a Reply. |
AuthorWrite something about yourself. No need to be fancy, just an overview. ArchivesCategories |