[clang-tidy] New checker for not null-terminated result caused by strlen(), size...
authorJonas Toth <jonas.toth@gmail.com>
Fri, 12 Oct 2018 17:22:36 +0000 (17:22 +0000)
committerJonas Toth <jonas.toth@gmail.com>
Fri, 12 Oct 2018 17:22:36 +0000 (17:22 +0000)
commit78886233b34d4803e29957377183266b15513bb3
tree3bcbddea779272ec494f25ef995d21bc5098b597
parent92d8a29ca0d506cea28718644527c4711ee3e694
[clang-tidy] New checker for not null-terminated result caused by strlen(), size() or equal length

New checker called bugprone-not-null-terminated-result. This check finds function calls where it is possible to cause a not null-terminated result. Usually the proper length of a string is strlen(src) + 1 or equal length of this expression, because the null terminator needs an extra space. Without the null terminator it can result in undefined behaviour when the string is read.

The following function calls are checked:
memcpy, wmemcpy, memcpy_s, wmemcpy_s, memchr, wmemchr, memmove, wmemmove, memmove_s, wmemmove_s, memset, wmemset, strerror_s, strncmp, wcsncmp, strxfrm, wcsxfrm

The following is a real-world example where the programmer forgot to increase the passed third argument, which is size_t length. That is why the length of the allocated memory is problematic too.

static char *StringCpy(const std::string &str) {
  char *result = reinterpret_cast<char *>(malloc(str.size()));
  memcpy(result, str.data(), str.size());
  return result;
}

After running the tool fix-it rewrites all the necessary code according to the given options. If it is necessary, the buffer size will be increased to hold the null terminator.

static char *StringCpy(const std::string &str) {
  char *result = reinterpret_cast<char *>(malloc(str.size() + 1));
  strcpy(result, str.data());
  return result;
}

Patch by Charusso.

Differential ID: https://reviews.llvm.org/D45050

llvm-svn: 344374
15 files changed:
clang-tools-extra/clang-tidy/bugprone/BugproneTidyModule.cpp
clang-tools-extra/clang-tidy/bugprone/CMakeLists.txt
clang-tools-extra/clang-tidy/bugprone/NotNullTerminatedResultCheck.cpp [new file with mode: 0644]
clang-tools-extra/clang-tidy/bugprone/NotNullTerminatedResultCheck.h [new file with mode: 0644]
clang-tools-extra/docs/ReleaseNotes.rst
clang-tools-extra/docs/clang-tidy/checks/bugprone-not-null-terminated-result.rst [new file with mode: 0644]
clang-tools-extra/docs/clang-tidy/checks/list.rst
clang-tools-extra/test/clang-tidy/bugprone-not-null-terminated-result-in-initialization-strlen.c [new file with mode: 0644]
clang-tools-extra/test/clang-tidy/bugprone-not-null-terminated-result-memcpy-before-safe.c [new file with mode: 0644]
clang-tools-extra/test/clang-tidy/bugprone-not-null-terminated-result-memcpy-safe-cxx.cpp [new file with mode: 0644]
clang-tools-extra/test/clang-tidy/bugprone-not-null-terminated-result-memcpy-safe-other.c [new file with mode: 0644]
clang-tools-extra/test/clang-tidy/bugprone-not-null-terminated-result-memcpy-safe.c [new file with mode: 0644]
clang-tools-extra/test/clang-tidy/bugprone-not-null-terminated-result-strlen.c [new file with mode: 0644]
clang-tools-extra/test/clang-tidy/bugprone-not-null-terminated-result-wcslen.cpp [new file with mode: 0644]
clang-tools-extra/test/clang-tidy/bugprone-not-null-terminated-result-wmemcpy-safe-cxx.cpp [new file with mode: 0644]