zukatsinadze created this revision.
zukatsinadze added reviewers: aaron.ballman, alexfh, hokein, Charusso.
zukatsinadze added projects: clang-tools-extra, clang.
Herald added subscribers: cfe-commits, mgehre, xazax.hun, mgorny.

According to
https://wiki.sei.cmu.edu/confluence/display/c/POS34-C.+Do+not+call+putenv%28%29+with+a+pointer+to+an+automatic+variable+as+the+argument
cert-pos34-c check is created. The check warns if `putenv` function is 
called with automatic storage variable as an argument.


Repository:
  rCTE Clang Tools Extra

https://reviews.llvm.org/D70823

Files:
  clang-tools-extra/clang-tidy/cert/CERTTidyModule.cpp
  clang-tools-extra/clang-tidy/cert/CMakeLists.txt
  clang-tools-extra/clang-tidy/cert/PutenvWithAutoCheck.cpp
  clang-tools-extra/clang-tidy/cert/PutenvWithAutoCheck.h
  clang-tools-extra/docs/ReleaseNotes.rst
  clang-tools-extra/docs/clang-tidy/checks/cert-pos34-c.rst
  clang-tools-extra/docs/clang-tidy/checks/list.rst
  clang-tools-extra/test/clang-tidy/cert-pos34-c.cpp

Index: clang-tools-extra/test/clang-tidy/cert-pos34-c.cpp
===================================================================
--- /dev/null
+++ clang-tools-extra/test/clang-tidy/cert-pos34-c.cpp
@@ -0,0 +1,64 @@
+// RUN: %check_clang_tidy %s cert-pos34-c %t
+#include <stdlib.h>
+#include <string.h>
+
+namespace test_auto_var_used_bad {
+
+int func1(const char *var) {
+  char env[1024];
+  /*
+  Do Something
+  */
+  return putenv(env);
+  // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: 'putenv' function should not be called with auto variables [cert-pos34-c]
+}
+
+int func2(char* a){
+  return putenv(a);
+  // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: 'putenv' function should not be called with auto variables [cert-pos34-c]
+}
+
+
+void func3(char* a){
+  putenv(a);
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: 'putenv' function should not be called with auto variables [cert-pos34-c]
+}
+
+} // namespace test_auto_var_used_bad
+
+namespace test_auto_var_used_good {
+
+int func4(const char *var) {
+  static char env[1024];
+  /*
+  Do Something
+  */
+  return putenv(env); // no-warning: env is static.
+}
+
+// example from cert
+int func5(const char *var) {
+  static char *oldenv;
+  const char *env_format = "TEST=%s";
+  const size_t len = strlen(var) + strlen(env_format);
+  char *env = (char *) malloc(len);
+  if (env == NULL) {
+    return -1;
+  }
+  if (putenv(env) != 0) { // no-warning: env was dynamically allocated.
+    free(env);
+    return -1;
+  }
+  if (oldenv != NULL) {
+    free(oldenv); /* avoid memory leak */
+  }
+  oldenv = env;
+  return 0;
+}
+
+extern char* testExt;
+int func6(){
+  return putenv(testExt); // no-warning: extern storage class.
+}
+
+} // namespace test_auto_var_used_good
Index: clang-tools-extra/docs/clang-tidy/checks/list.rst
===================================================================
--- clang-tools-extra/docs/clang-tidy/checks/list.rst
+++ clang-tools-extra/docs/clang-tidy/checks/list.rst
@@ -102,6 +102,7 @@
    cert-msc51-cpp
    cert-oop11-cpp (redirects to performance-move-constructor-init) <cert-oop11-cpp>
    cert-oop54-cpp (redirects to bugprone-unhandled-self-assignment) <cert-oop54-cpp>
+   cert-pos34-c
    cppcoreguidelines-avoid-c-arrays (redirects to modernize-avoid-c-arrays) <cppcoreguidelines-avoid-c-arrays>
    cppcoreguidelines-avoid-goto
    cppcoreguidelines-avoid-magic-numbers (redirects to readability-magic-numbers) <cppcoreguidelines-avoid-magic-numbers>
Index: clang-tools-extra/docs/clang-tidy/checks/cert-pos34-c.rst
===================================================================
--- /dev/null
+++ clang-tools-extra/docs/clang-tidy/checks/cert-pos34-c.rst
@@ -0,0 +1,25 @@
+.. title:: clang-tidy - cert-pos34-c
+
+cert-pos34-c
+=====================
+
+Finds calls of ``putenv`` function with automatic variable as the argument.
+
+.. code-block:: c
+
+  #include <stdlib.h>
+
+  int func(const char *var) {
+    char env[1024];
+    int retval = snprintf(env, sizeof(env),"TEST=%s", var);
+    if (retval < 0 || (size_t)retval >= sizeof(env)) {
+        /* Handle error */
+    }
+ 
+    return putenv(env); // putenv function should not be called with auto variables
+  }
+
+
+This check corresponds to the CERT Standard rule 
+`POS34-C. Do not call putenv() with a pointer to an automatic variable as the argument.
+<https://wiki.sei.cmu.edu/confluence/display/c/POS34-C.+Do+not+call+putenv%28%29+with+a+pointer+to+an+automatic+variable+as+the+argument>`_.
Index: clang-tools-extra/docs/ReleaseNotes.rst
===================================================================
--- clang-tools-extra/docs/ReleaseNotes.rst
+++ clang-tools-extra/docs/ReleaseNotes.rst
@@ -194,6 +194,11 @@
   against self-assignment either by checking self-assignment explicitly or
   using the copy-and-swap or the copy-and-move method.
 
+- New :doc:`cert-pos34-c
+  <clang-tidy/checks/cert-pos34-c>` check.
+
+  Finds calls of 'putenv' function with automatic variable as the argument.
+
 - New :doc:`fuchsia-default-arguments-calls
   <clang-tidy/checks/fuchsia-default-arguments-calls>` check.
 
Index: clang-tools-extra/clang-tidy/cert/PutenvWithAutoCheck.h
===================================================================
--- /dev/null
+++ clang-tools-extra/clang-tidy/cert/PutenvWithAutoCheck.h
@@ -0,0 +1,35 @@
+//===--- PutenvWithAutoCheck.h - clang-tidy ---------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CERT_PUTENV_WITH_AUTO_H
+#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CERT_PUTENV_WITH_AUTO_H
+
+#include "../ClangTidyCheck.h"
+
+namespace clang {
+namespace tidy {
+namespace cert {
+
+/// Finds calls of putenv function with automatic variable as the argument.
+
+///
+/// For the user-facing documentation see:
+/// http://clang.llvm.org/extra/clang-tidy/checks/cert-pos34-c.html
+class PutenvWithAutoCheck : public ClangTidyCheck {
+public:
+  PutenvWithAutoCheck(StringRef Name, ClangTidyContext *Context)
+      : ClangTidyCheck(Name, Context) {}
+  void registerMatchers(ast_matchers::MatchFinder *Finder) override;
+  void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
+};
+
+} // namespace cert
+} // namespace tidy
+} // namespace clang
+
+#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CERT_PUTENV_WITH_AUTO_H
\ No newline at end of file
Index: clang-tools-extra/clang-tidy/cert/PutenvWithAutoCheck.cpp
===================================================================
--- /dev/null
+++ clang-tools-extra/clang-tidy/cert/PutenvWithAutoCheck.cpp
@@ -0,0 +1,42 @@
+//===--- PutenvWithAutoCheck.cpp - clang-tidy -----------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "PutenvWithAutoCheck.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+
+using namespace clang::ast_matchers;
+
+namespace clang {
+namespace tidy {
+namespace cert {
+
+void PutenvWithAutoCheck::registerMatchers(MatchFinder *Finder) {
+  Finder->addMatcher(
+      callExpr(
+          callee(functionDecl(hasName("::putenv"))),
+          hasArgument(
+              0,
+              declRefExpr(hasDeclaration(varDecl(
+                  hasAutomaticStorageDuration(),
+                  unless(hasDescendant(callExpr(callee(functionDecl(hasAnyName(
+                      "::alloc", "::malloc", "::realloc", "::calloc")))))))))))
+          .bind("func"),
+      this);
+}
+
+void PutenvWithAutoCheck::check(const MatchFinder::MatchResult &Result) {
+  const auto *MatchedDecl = Result.Nodes.getNodeAs<CallExpr>("func");
+
+  diag(MatchedDecl->getBeginLoc(),
+       "'putenv' function should not be called with auto variables");
+}
+
+} // namespace cert
+} // namespace tidy
+} // namespace clang
Index: clang-tools-extra/clang-tidy/cert/CMakeLists.txt
===================================================================
--- clang-tools-extra/clang-tidy/cert/CMakeLists.txt
+++ clang-tools-extra/clang-tidy/cert/CMakeLists.txt
@@ -8,6 +8,7 @@
   LimitedRandomnessCheck.cpp
   PostfixOperatorCheck.cpp
   ProperlySeededRandomGeneratorCheck.cpp
+  PutenvWithAutoCheck.cpp
   SetLongJmpCheck.cpp
   StaticObjectExceptionCheck.cpp
   StrToNumCheck.cpp
Index: clang-tools-extra/clang-tidy/cert/CERTTidyModule.cpp
===================================================================
--- clang-tools-extra/clang-tidy/cert/CERTTidyModule.cpp
+++ clang-tools-extra/clang-tidy/cert/CERTTidyModule.cpp
@@ -23,6 +23,7 @@
 #include "LimitedRandomnessCheck.h"
 #include "PostfixOperatorCheck.h"
 #include "ProperlySeededRandomGeneratorCheck.h"
+#include "PutenvWithAutoCheck.h"
 #include "SetLongJmpCheck.h"
 #include "StaticObjectExceptionCheck.h"
 #include "StrToNumCheck.h"
@@ -82,6 +83,8 @@
     CheckFactories.registerCheck<LimitedRandomnessCheck>("cert-msc30-c");
     CheckFactories.registerCheck<ProperlySeededRandomGeneratorCheck>(
         "cert-msc32-c");
+    // POS
+    CheckFactories.registerCheck<PutenvWithAutoCheck>("cert-pos34-c");
   }
 
   ClangTidyOptions getModuleOptions() override {
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to