xref: /llvm-project/clang-tools-extra/docs/clang-tidy/checks/bugprone/not-null-terminated-result.rst (revision 6e566bc5523f743bc34a7e26f050f1f2b4d699a8)
1.. title:: clang-tidy - bugprone-not-null-terminated-result
2
3bugprone-not-null-terminated-result
4===================================
5
6Finds function calls where it is possible to cause a not null-terminated result.
7Usually the proper length of a string is ``strlen(src) + 1`` or equal length of
8this expression, because the null terminator needs an extra space. Without the
9null terminator it can result in undefined behavior when the string is read.
10
11The following and their respective ``wchar_t`` based functions are checked:
12
13``memcpy``, ``memcpy_s``, ``memchr``, ``memmove``, ``memmove_s``,
14``strerror_s``, ``strncmp``, ``strxfrm``
15
16The following is a real-world example where the programmer forgot to increase
17the passed third argument, which is ``size_t length``. That is why the length
18of the allocated memory is not enough to hold the null terminator.
19
20.. code-block:: c
21
22  static char *stringCpy(const std::string &str) {
23    char *result = reinterpret_cast<char *>(malloc(str.size()));
24    memcpy(result, str.data(), str.size());
25    return result;
26  }
27
28In addition to issuing warnings, fix-it rewrites all the necessary code. It also
29tries to adjust the capacity of the destination array:
30
31.. code-block:: c
32
33  static char *stringCpy(const std::string &str) {
34    char *result = reinterpret_cast<char *>(malloc(str.size() + 1));
35    strcpy(result, str.data());
36    return result;
37  }
38
39Note: It cannot guarantee to rewrite every of the path-sensitive memory
40allocations.
41
42.. _MemcpyTransformation:
43
44Transformation rules of 'memcpy()'
45----------------------------------
46
47It is possible to rewrite the ``memcpy()`` and ``memcpy_s()`` calls as the
48following four functions:  ``strcpy()``, ``strncpy()``, ``strcpy_s()``,
49``strncpy_s()``, where the latter two are the safer versions of the former two.
50It rewrites the ``wchar_t`` based memory handler functions respectively.
51
52Rewrite based on the destination array
53^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
54
55- If copy to the destination array cannot overflow [1] the new function should
56  be the older copy function (ending with ``cpy``), because it is more
57  efficient than the safe version.
58
59- If copy to the destination array can overflow [1] and
60  :option:`WantToUseSafeFunctions` is set to `true` and it is possible to
61  obtain the capacity of the destination array then the new function could be
62  the safe version (ending with ``cpy_s``).
63
64- If the new function is could be safe version and C++ files are analyzed and
65  the destination array is plain ``char``/``wchar_t`` without ``un/signed`` then
66  the length of the destination array can be omitted.
67
68- If the new function is could be safe version and the destination array is
69  ``un/signed`` it needs to be casted to plain ``char *``/``wchar_t *``.
70
71[1] It is possible to overflow:
72  - If the capacity of the destination array is unknown.
73  - If the given length is equal to the destination array's capacity.
74
75Rewrite based on the length of the source string
76^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
77
78- If the given length is ``strlen(source)`` or equal length of this expression
79  then the new function should be the older copy function (ending with ``cpy``),
80  as it is more efficient than the safe version (ending with ``cpy_s``).
81
82- Otherwise we assume that the programmer wanted to copy 'N' characters, so the
83  new function is ``ncpy``-like which copies 'N' characters.
84
85Transformations with 'strlen()' or equal length of this expression
86------------------------------------------------------------------
87
88It transforms the ``wchar_t`` based memory and string handler functions
89respectively (where only ``strerror_s`` does not have ``wchar_t`` based alias).
90
91Memory handler functions
92^^^^^^^^^^^^^^^^^^^^^^^^
93
94``memcpy``
95Please visit the
96:ref:`Transformation rules of 'memcpy()'<MemcpyTransformation>` section.
97
98``memchr``
99Usually there is a C-style cast and it is needed to be removed, because the
100new function ``strchr``'s return type is correct. The given length is going
101to be removed.
102
103``memmove``
104If safe functions are available the new function is ``memmove_s``, which has
105a new second argument which is the length of the destination array, it is
106adjusted, and the length of the source string is incremented by one.
107If safe functions are not available the given length is incremented by one.
108
109``memmove_s``
110The given length is incremented by one.
111
112String handler functions
113^^^^^^^^^^^^^^^^^^^^^^^^
114
115``strerror_s``
116The given length is incremented by one.
117
118``strncmp``
119If the third argument is the first or the second argument's ``length + 1``
120it has to be truncated without the ``+ 1`` operation.
121
122``strxfrm``
123The given length is incremented by one.
124
125Options
126-------
127
128.. option::  WantToUseSafeFunctions
129
130   The value `true` specifies that the target environment is considered to
131   implement '_s' suffixed memory and string handler functions which are safer
132   than older versions (e.g. 'memcpy_s()'). The default value is `true`.
133