Hi djasper,
ClangTidy and its frontends rely on check names being restricted to
certain rules, e.g. having a comma in a check name would break -checks=
parameter parsing. So we need to validate check names early.
http://reviews.llvm.org/D4982
Files:
clang-tidy/ClangTidy.cpp
clang-tidy/ClangTidy.h
clang-tidy/ClangTidyModule.cpp
unittests/clang-tidy/CMakeLists.txt
unittests/clang-tidy/ClangTidyTest.cpp
Index: clang-tidy/ClangTidy.cpp
===================================================================
--- clang-tidy/ClangTidy.cpp
+++ clang-tidy/ClangTidy.cpp
@@ -37,6 +37,7 @@
#include "clang/Tooling/Tooling.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/Process.h"
+#include "llvm/Support/Regex.h"
#include "llvm/Support/Signals.h"
#include <algorithm>
#include <utility>
@@ -290,6 +291,11 @@
for (StringRef CheckName : StaticAnalyzerChecks) {
std::string Checker((AnalyzerCheckNamePrefix + CheckName).str());
+ if (!ClangTidyCheck::isValidCheckName(Checker)) {
+ assert(false &&
+ "Static analyzer check name contains invalid characters");
+ continue;
+ }
if (CheckName.startswith("core") ||
(!CheckName.startswith("debug") && Filter.contains(Checker)))
List.push_back(std::make_pair(CheckName, true));
@@ -313,6 +319,10 @@
CheckName = Name.str();
}
+bool ClangTidyCheck::isValidCheckName(StringRef Name) {
+ return llvm::Regex("^[a-zA-Z0-9_.\\-]+$").match(Name);
+}
+
std::vector<std::string> getCheckNames(const ClangTidyOptions &Options) {
clang::tidy::ClangTidyContext Context(
new DefaultOptionsProvider(ClangTidyGlobalOptions(), Options));
Index: clang-tidy/ClangTidy.h
===================================================================
--- clang-tidy/ClangTidy.h
+++ clang-tidy/ClangTidy.h
@@ -86,6 +86,12 @@
/// framework. Can be called only once.
void setName(StringRef Name);
+ /// \brief Returns \c true, if the specified string can be used for a check
+ /// name.
+ ///
+ /// Only alphanumeric characters, '-', '_' and '.' are allowed in check names.
+ static bool isValidCheckName(StringRef Name);
+
private:
void run(const ast_matchers::MatchFinder::MatchResult &Result) override;
ClangTidyContext *Context;
Index: clang-tidy/ClangTidyModule.cpp
===================================================================
--- clang-tidy/ClangTidyModule.cpp
+++ clang-tidy/ClangTidyModule.cpp
@@ -29,6 +29,10 @@
void ClangTidyCheckFactories::createChecks(
GlobList &Filter, std::vector<std::unique_ptr<ClangTidyCheck>> &Checks) {
for (const auto &Factory : Factories) {
+ if (!ClangTidyCheck::isValidCheckName(Factory.first)) {
+ assert(false && "ClangTidy check name contains invalid characters");
+ continue;
+ }
if (Filter.contains(Factory.first)) {
ClangTidyCheck *Check = Factory.second->createCheck();
Check->setName(Factory.first);
Index: unittests/clang-tidy/CMakeLists.txt
===================================================================
--- unittests/clang-tidy/CMakeLists.txt
+++ unittests/clang-tidy/CMakeLists.txt
@@ -9,6 +9,7 @@
add_extra_unittest(ClangTidyTests
ClangTidyDiagnosticConsumerTest.cpp
ClangTidyOptionsTest.cpp
+ ClangTidyTest.cpp
LLVMModuleTest.cpp
GoogleModuleTest.cpp
MiscModuleTest.cpp)
Index: unittests/clang-tidy/ClangTidyTest.cpp
===================================================================
--- /dev/null
+++ unittests/clang-tidy/ClangTidyTest.cpp
@@ -0,0 +1,18 @@
+#include "ClangTidy.h"
+#include "gtest/gtest.h"
+
+namespace clang {
+namespace tidy {
+namespace test {
+
+TEST(ClangTidyCheck, IsValidCheckName) {
+ EXPECT_TRUE(ClangTidyCheck::isValidCheckName("asdf123-xxx_yyy.YYY.ZZZ"));
+ EXPECT_FALSE(ClangTidyCheck::isValidCheckName(""));
+ EXPECT_FALSE(ClangTidyCheck::isValidCheckName("a b"));
+ EXPECT_FALSE(ClangTidyCheck::isValidCheckName("ab "));
+ EXPECT_FALSE(ClangTidyCheck::isValidCheckName("ab!"));
+}
+
+} // namespace test
+} // namespace tidy
+} // namespace clang
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits