brintos

brintos / llvm-project-archived public Read only

0
0
Text · 4.9 KiB · db86e94 Raw
135 lines · plain
1.. title:: clang-tidy - bugprone-not-null-terminated-result2 3bugprone-not-null-terminated-result4===================================5 6Finds function calls where it is possible to cause a not null-terminated7result. Usually the proper length of a string is ``strlen(src) + 1`` or equal8length of this expression, because the null terminator needs an extra space.9Without the null terminator it can result in undefined behavior when the10string is read.11 12The following and their respective ``wchar_t`` based functions are checked:13 14``memcpy``, ``memcpy_s``, ``memchr``, ``memmove``, ``memmove_s``,15``strerror_s``, ``strncmp``, ``strxfrm``16 17The following is a real-world example where the programmer forgot to increase18the passed third argument, which is ``size_t length``. That is why the length19of the allocated memory is not enough to hold the null terminator.20 21.. code-block:: c22 23  static char *stringCpy(const std::string &str) {24    char *result = reinterpret_cast<char *>(malloc(str.size()));25    memcpy(result, str.data(), str.size());26    return result;27  }28 29In addition to issuing warnings, fix-it rewrites all the necessary code.30It also tries to adjust the capacity of the destination array:31 32.. code-block:: c33 34  static char *stringCpy(const std::string &str) {35    char *result = reinterpret_cast<char *>(malloc(str.size() + 1));36    strcpy(result, str.data());37    return result;38  }39 40Note: It cannot guarantee to rewrite every of the path-sensitive memory41allocations.42 43.. _MemcpyTransformation:44 45Transformation rules of 'memcpy()'46----------------------------------47 48It is possible to rewrite the ``memcpy()`` and ``memcpy_s()`` calls as the49following four functions:  ``strcpy()``, ``strncpy()``, ``strcpy_s()``,50``strncpy_s()``, where the latter two are the safer versions of the former two.51It rewrites the ``wchar_t`` based memory handler functions respectively.52 53Rewrite based on the destination array54^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^55 56- If copy to the destination array cannot overflow [1] the new function should57  be the older copy function (ending with ``cpy``), because it is more58  efficient than the safe version.59 60- If copy to the destination array can overflow [1] and61  :option:`WantToUseSafeFunctions` is set to `true` and it is possible to62  obtain the capacity of the destination array then the new function could be63  the safe version (ending with ``cpy_s``).64 65- If the new function is could be safe version and C++ files are analyzed and66  the destination array is plain ``char``/``wchar_t`` without ``un/signed``67  then the length of the destination array can be omitted.68 69- If the new function is could be safe version and the destination array is70  ``un/signed`` it needs to be casted to plain ``char *``/``wchar_t *``.71 72[1] It is possible to overflow:73  - If the capacity of the destination array is unknown.74  - If the given length is equal to the destination array's capacity.75 76Rewrite based on the length of the source string77^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^78 79- If the given length is ``strlen(source)`` or equal length of this expression80  then the new function should be the older copy function (ending with81  ``cpy``), as it is more efficient than the safe version (ending with82  ``cpy_s``).83 84- Otherwise we assume that the programmer wanted to copy 'N' characters, so the85  new function is ``ncpy``-like which copies 'N' characters.86 87Transformations with 'strlen()' or equal length of this expression88------------------------------------------------------------------89 90It transforms the ``wchar_t`` based memory and string handler functions91respectively (where only ``strerror_s`` does not have ``wchar_t`` based alias).92 93Memory handler functions94^^^^^^^^^^^^^^^^^^^^^^^^95 96``memcpy``97Please visit the98:ref:`Transformation rules of 'memcpy()'<MemcpyTransformation>` section.99 100``memchr``101Usually there is a C-style cast and it is needed to be removed, because the102new function ``strchr``'s return type is correct. The given length is going103to be removed.104 105``memmove``106If safe functions are available the new function is ``memmove_s``, which has107a new second argument which is the length of the destination array, it is108adjusted, and the length of the source string is incremented by one.109If safe functions are not available the given length is incremented by one.110 111``memmove_s``112The given length is incremented by one.113 114String handler functions115^^^^^^^^^^^^^^^^^^^^^^^^116 117``strerror_s``118The given length is incremented by one.119 120``strncmp``121If the third argument is the first or the second argument's ``length + 1``122it has to be truncated without the ``+ 1`` operation.123 124``strxfrm``125The given length is incremented by one.126 127Options128-------129 130.. option::  WantToUseSafeFunctions131 132   The value `true` specifies that the target environment is considered to133   implement '_s' suffixed memory and string handler functions which are safer134   than older versions (e.g. 'memcpy_s()'). The default value is `true`.135