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