Yoorkin updated this revision to Diff 454228.
Yoorkin added a comment.

I fixed it. Thanks


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D132294/new/

https://reviews.llvm.org/D132294

Files:
  clang-tools-extra/clang-tidy/bugprone/BugproneTidyModule.cpp
  clang-tools-extra/clang-tidy/bugprone/CMakeLists.txt
  clang-tools-extra/clang-tidy/bugprone/SprintfWithFixedSizeBufferCheck.cpp
  clang-tools-extra/clang-tidy/bugprone/SprintfWithFixedSizeBufferCheck.h
  clang-tools-extra/docs/ReleaseNotes.rst
  
clang-tools-extra/docs/clang-tidy/checks/bugprone/sprintf-with-fixed-size-buffer.rst
  clang-tools-extra/docs/clang-tidy/checks/list.rst
  
clang-tools-extra/test/clang-tidy/checkers/bugprone/sprintf-with-fixed-size-buffer.cpp

Index: clang-tools-extra/test/clang-tidy/checkers/bugprone/sprintf-with-fixed-size-buffer.cpp
===================================================================
--- /dev/null
+++ clang-tools-extra/test/clang-tidy/checkers/bugprone/sprintf-with-fixed-size-buffer.cpp
@@ -0,0 +1,24 @@
+// RUN: %check_clang_tidy %s bugprone-sprintf-with-fixed-size-buffer %t
+
+#include <stdio.h>
+
+void f(){
+  char buff[80];
+  sprintf(buff, "Hello, %s!\n", "world");
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: string to be written may exceeds the size of buffer; use snprintf instead [bugprone-sprintf-with-fixed-size-buffer]
+  // CHECK-FIXES: snprintf(buff, sizeof(buff), "Hello, %s!\n", "world");
+}
+
+
+char sbuff[80];
+
+void f2(){
+  sprintf(sbuff, "Hello, %s!\n", "world");
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: string to be written may exceeds the size of buffer; use snprintf instead [bugprone-sprintf-with-fixed-size-buffer]
+  // CHECK-FIXES: snprintf(sbuff, sizeof(sbuff), "Hello, %s!\n", "world");
+}
+
+void f3(){
+    char *dynamic_sized_buff = nullptr;
+    sprintf(dynamic_sized_buff, "Hello, %s!\n", "world");
+}
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
@@ -114,6 +114,7 @@
    `bugprone-signed-char-misuse <bugprone/signed-char-misuse.html>`_,
    `bugprone-sizeof-container <bugprone/sizeof-container.html>`_,
    `bugprone-sizeof-expression <bugprone/sizeof-expression.html>`_,
+   `bugprone-sprintf-with-fixed-size-buffer <bugprone/sprintf-with-fixed-size-buffer.html>`_, "Yes"
    `bugprone-spuriously-wake-up-functions <bugprone/spuriously-wake-up-functions.html>`_,
    `bugprone-string-constructor <bugprone/string-constructor.html>`_, "Yes"
    `bugprone-string-integer-assignment <bugprone/string-integer-assignment.html>`_, "Yes"
Index: clang-tools-extra/docs/clang-tidy/checks/bugprone/sprintf-with-fixed-size-buffer.rst
===================================================================
--- /dev/null
+++ clang-tools-extra/docs/clang-tidy/checks/bugprone/sprintf-with-fixed-size-buffer.rst
@@ -0,0 +1,27 @@
+.. title:: clang-tidy - bugprone-sprintf-with-fixed-size-buffer
+
+bugprone-sprintf-with-fixed-size-buffer
+=======================================
+
+Finds usage of ``sprintf``, which write output string into a fixed-size array. It 
+will suggest ``snprintf`` instead.
+
+It's a common idiom to have a fixed-size buffer of characters allocated on 
+the stack and then to printf into the buffer. It may be leading to errors if the 
+string to be written exceeds the size of the array pointed to by buffer.
+
+Example:
+.. code-block:: c++
+
+    void f(){
+      char buff[80];
+      sprintf(buff, "Hello, %s!\n", "world");
+    }
+
+Becomes:
+.. code-block:: c++
+
+    void f(){
+      char buff[80];
+      snprintf(buff, sizeof(buff), "Hello, %s!\n", "world");
+    }
Index: clang-tools-extra/docs/ReleaseNotes.rst
===================================================================
--- clang-tools-extra/docs/ReleaseNotes.rst
+++ clang-tools-extra/docs/ReleaseNotes.rst
@@ -99,6 +99,11 @@
 New checks
 ^^^^^^^^^^
 
+- New :doc:`bugprone-sprintf-with-fixed-size-buffer
+  <clang-tidy/checks/bugprone/sprintf-with-fixed-size-buffer>` check.
+
+  Finds usage of ``sprintf``, which write output string into a fixed-size array.
+
 - New :doc:`cppcoreguidelines-avoid-const-or-ref-data-members
   <clang-tidy/checks/cppcoreguidelines/avoid-const-or-ref-data-members>` check.
 
Index: clang-tools-extra/clang-tidy/bugprone/SprintfWithFixedSizeBufferCheck.h
===================================================================
--- /dev/null
+++ clang-tools-extra/clang-tidy/bugprone/SprintfWithFixedSizeBufferCheck.h
@@ -0,0 +1,38 @@
+//===--- SprintfWithFixedSizeBufferCheck.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_BUGPRONE_SPRINTFWITHFIXEDSIZEBUFFERCHECK_H
+#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_BUGPRONE_SPRINTFWITHFIXEDSIZEBUFFERCHECK_H
+
+#include "../ClangTidyCheck.h"
+
+namespace clang {
+namespace tidy {
+namespace bugprone {
+
+/// Check if `sprintf` is called with a fixed size buffer. Replaced with counted
+/// version `snprintf`.
+///
+/// For the user-facing documentation see:
+/// http://clang.llvm.org/extra/clang-tidy/checks/bugprone/sprintf-with-fixed-size-buffer.html
+class SprintfWithFixedSizeBufferCheck : public ClangTidyCheck {
+public:
+  SprintfWithFixedSizeBufferCheck(StringRef Name, ClangTidyContext *Context)
+      : ClangTidyCheck(Name, Context) {}
+  bool isLanguageVersionSupported(const LangOptions &LangOpts) const override {
+    return LangOpts.CPlusPlus;
+  }
+  void registerMatchers(ast_matchers::MatchFinder *Finder) override;
+  void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
+};
+
+} // namespace bugprone
+} // namespace tidy
+} // namespace clang
+
+#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_BUGPRONE_SPRINTFWITHFIXEDSIZEBUFFERCHECK_H
Index: clang-tools-extra/clang-tidy/bugprone/SprintfWithFixedSizeBufferCheck.cpp
===================================================================
--- /dev/null
+++ clang-tools-extra/clang-tidy/bugprone/SprintfWithFixedSizeBufferCheck.cpp
@@ -0,0 +1,72 @@
+//===--- SprintfWithFixedSizeBufferCheck.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 "SprintfWithFixedSizeBufferCheck.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/Expr.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+#include "clang/Lex/Lexer.h"
+#include "llvm/ADT/StringRef.h"
+
+using namespace clang::ast_matchers;
+
+namespace clang {
+namespace tidy {
+namespace bugprone {
+
+void SprintfWithFixedSizeBufferCheck::registerMatchers(MatchFinder *Finder) {
+  Finder->addMatcher(
+      callExpr(allOf(hasArgument(0, declRefExpr(hasType(constantArrayType()))
+                                        .bind("ConstantArray")),
+                     callee(functionDecl(hasName("::sprintf")))))
+          .bind("sprintf"),
+      this);
+}
+
+void SprintfWithFixedSizeBufferCheck::check(
+    const MatchFinder::MatchResult &Result) {
+  const auto *CA = Result.Nodes.getNodeAs<DeclRefExpr>("ConstantArray");
+  const auto *Call = Result.Nodes.getNodeAs<CallExpr>("sprintf");
+
+  std::string ReplacementText = "snprintf(";
+  auto arg = Call->getArgs();
+
+  // Get first argument.
+  SourceRange SrcRange = arg[0]->getSourceRange();
+  ReplacementText +=
+      Lexer::getSourceText(CharSourceRange::getTokenRange(SrcRange),
+                           *Result.SourceManager, getLangOpts());
+
+  // Insert the size of buffer after first argument.
+  ReplacementText += ", sizeof(";
+  ReplacementText +=
+      Lexer::getSourceText(CharSourceRange::getTokenRange(CA->getSourceRange()),
+                           *Result.SourceManager, getLangOpts());
+  ReplacementText += ")";
+
+  // Process the remaining arguments.
+  for (unsigned i = 1; i < Call->getNumArgs(); i++) {
+    ReplacementText += ", ";
+    ReplacementText += Lexer::getSourceText(
+        CharSourceRange::getTokenRange(arg[i]->getSourceRange()),
+        *Result.SourceManager, getLangOpts());
+  }
+
+  ReplacementText += ')';
+
+  FixItHint hint =
+      FixItHint::CreateReplacement(Call->getSourceRange(), ReplacementText);
+
+  diag(Call->getBeginLoc(), "string to be written may exceeds the size of "
+                            "buffer; use snprintf instead")
+      << SourceRange(Call->getBeginLoc(), Call->getEndLoc()) << hint;
+}
+
+} // namespace bugprone
+} // namespace tidy
+} // namespace clang
Index: clang-tools-extra/clang-tidy/bugprone/CMakeLists.txt
===================================================================
--- clang-tools-extra/clang-tidy/bugprone/CMakeLists.txt
+++ clang-tools-extra/clang-tidy/bugprone/CMakeLists.txt
@@ -44,6 +44,7 @@
   SignedCharMisuseCheck.cpp
   SizeofContainerCheck.cpp
   SizeofExpressionCheck.cpp
+  SprintfWithFixedSizeBufferCheck.cpp
   SpuriouslyWakeUpFunctionsCheck.cpp
   StringConstructorCheck.cpp
   StringIntegerAssignmentCheck.cpp
Index: clang-tools-extra/clang-tidy/bugprone/BugproneTidyModule.cpp
===================================================================
--- clang-tools-extra/clang-tidy/bugprone/BugproneTidyModule.cpp
+++ clang-tools-extra/clang-tidy/bugprone/BugproneTidyModule.cpp
@@ -48,6 +48,7 @@
 #include "SignedCharMisuseCheck.h"
 #include "SizeofContainerCheck.h"
 #include "SizeofExpressionCheck.h"
+#include "SprintfWithFixedSizeBufferCheck.h"
 #include "SpuriouslyWakeUpFunctionsCheck.h"
 #include "StringConstructorCheck.h"
 #include "StringIntegerAssignmentCheck.h"
@@ -153,6 +154,8 @@
         "bugprone-sizeof-container");
     CheckFactories.registerCheck<SizeofExpressionCheck>(
         "bugprone-sizeof-expression");
+    CheckFactories.registerCheck<SprintfWithFixedSizeBufferCheck>(
+        "bugprone-sprintf-with-fixed-size-buffer");
     CheckFactories.registerCheck<SpuriouslyWakeUpFunctionsCheck>(
         "bugprone-spuriously-wake-up-functions");
     CheckFactories.registerCheck<StringConstructorCheck>(
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to