Преглед на файлове

cmCacheManager: Truncate values containing newlines

Fixes #16098.
Kyle Edwards преди 7 години
родител
ревизия
a9c483071e
променени са 5 файла, в които са добавени 88 реда и са изтрити 12 реда
  1. 70 4
      Source/cmCacheManager.cxx
  2. 13 4
      Source/cmCacheManager.h
  3. 2 2
      Source/cmState.cxx
  4. 2 1
      Source/cmState.h
  5. 1 1
      Source/cmake.cxx

+ 70 - 4
Source/cmCacheManager.cxx

@@ -10,6 +10,7 @@
 #include <string.h>
 #include <string.h>
 
 
 #include "cmGeneratedFileStream.h"
 #include "cmGeneratedFileStream.h"
+#include "cmMessenger.h"
 #include "cmState.h"
 #include "cmState.h"
 #include "cmSystemTools.h"
 #include "cmSystemTools.h"
 #include "cmVersion.h"
 #include "cmVersion.h"
@@ -205,7 +206,8 @@ bool cmCacheManager::ReadPropertyEntry(std::string const& entryKey,
   return false;
   return false;
 }
 }
 
 
-void cmCacheManager::WritePropertyEntries(std::ostream& os, CacheIterator i)
+void cmCacheManager::WritePropertyEntries(std::ostream& os, CacheIterator i,
+                                          cmMessenger* messenger)
 {
 {
   for (const char** p = this->PersistentProperties; *p; ++p) {
   for (const char** p = this->PersistentProperties; *p; ++p) {
     if (const char* value = i.GetProperty(*p)) {
     if (const char* value = i.GetProperty(*p)) {
@@ -221,11 +223,13 @@ void cmCacheManager::WritePropertyEntries(std::ostream& os, CacheIterator i)
       os << ":INTERNAL=";
       os << ":INTERNAL=";
       this->OutputValue(os, value);
       this->OutputValue(os, value);
       os << "\n";
       os << "\n";
+      cmCacheManager::OutputNewlineTruncationWarning(os, key, value,
+                                                     messenger);
     }
     }
   }
   }
 }
 }
 
 
-bool cmCacheManager::SaveCache(const std::string& path)
+bool cmCacheManager::SaveCache(const std::string& path, cmMessenger* messenger)
 {
 {
   std::string cacheFile = path;
   std::string cacheFile = path;
   cacheFile += "/CMakeCache.txt";
   cacheFile += "/CMakeCache.txt";
@@ -316,7 +320,10 @@ bool cmCacheManager::SaveCache(const std::string& path)
       this->OutputKey(fout, i.first);
       this->OutputKey(fout, i.first);
       fout << ":" << cmState::CacheEntryTypeToString(t) << "=";
       fout << ":" << cmState::CacheEntryTypeToString(t) << "=";
       this->OutputValue(fout, ce.Value);
       this->OutputValue(fout, ce.Value);
-      fout << "\n\n";
+      fout << "\n";
+      cmCacheManager::OutputNewlineTruncationWarning(fout, i.first, ce.Value,
+                                                     messenger);
+      fout << "\n";
     }
     }
   }
   }
 
 
@@ -333,7 +340,7 @@ bool cmCacheManager::SaveCache(const std::string& path)
     }
     }
 
 
     cmStateEnums::CacheEntryType t = i.GetType();
     cmStateEnums::CacheEntryType t = i.GetType();
-    this->WritePropertyEntries(fout, i);
+    this->WritePropertyEntries(fout, i, messenger);
     if (t == cmStateEnums::INTERNAL) {
     if (t == cmStateEnums::INTERNAL) {
       // Format is key:type=value
       // Format is key:type=value
       if (const char* help = i.GetProperty("HELPSTRING")) {
       if (const char* help = i.GetProperty("HELPSTRING")) {
@@ -343,6 +350,8 @@ bool cmCacheManager::SaveCache(const std::string& path)
       fout << ":" << cmState::CacheEntryTypeToString(t) << "=";
       fout << ":" << cmState::CacheEntryTypeToString(t) << "=";
       this->OutputValue(fout, i.GetValue());
       this->OutputValue(fout, i.GetValue());
       fout << "\n";
       fout << "\n";
+      cmCacheManager::OutputNewlineTruncationWarning(fout, i.GetName(),
+                                                     i.GetValue(), messenger);
     }
     }
   }
   }
   fout << "\n";
   fout << "\n";
@@ -389,6 +398,19 @@ void cmCacheManager::OutputKey(std::ostream& fout, std::string const& key)
 }
 }
 
 
 void cmCacheManager::OutputValue(std::ostream& fout, std::string const& value)
 void cmCacheManager::OutputValue(std::ostream& fout, std::string const& value)
+{
+  // look for and truncate newlines
+  std::string::size_type newline = value.find('\n');
+  if (newline != std::string::npos) {
+    std::string truncated = value.substr(0, newline);
+    OutputValueNoNewlines(fout, truncated);
+  } else {
+    OutputValueNoNewlines(fout, value);
+  }
+}
+
+void cmCacheManager::OutputValueNoNewlines(std::ostream& fout,
+                                           std::string const& value)
 {
 {
   // if value has trailing space or tab, enclose it in single quotes
   // if value has trailing space or tab, enclose it in single quotes
   if (!value.empty() &&
   if (!value.empty() &&
@@ -423,6 +445,50 @@ void cmCacheManager::OutputHelpString(std::ostream& fout,
   }
   }
 }
 }
 
 
+void cmCacheManager::OutputWarningComment(std::ostream& fout,
+                                          std::string const& message,
+                                          bool wrapSpaces)
+{
+  std::string::size_type end = message.size();
+  std::string oneLine;
+  std::string::size_type pos = 0;
+  for (std::string::size_type i = 0; i <= end; i++) {
+    if ((i == end) || (message[i] == '\n') ||
+        ((i - pos >= 60) && (message[i] == ' ') && wrapSpaces)) {
+      fout << "# ";
+      if (message[pos] == '\n') {
+        pos++;
+        fout << "\\n";
+      }
+      oneLine = message.substr(pos, i - pos);
+      fout << oneLine << "\n";
+      pos = i;
+    }
+  }
+}
+
+void cmCacheManager::OutputNewlineTruncationWarning(std::ostream& fout,
+                                                    std::string const& key,
+                                                    std::string const& value,
+                                                    cmMessenger* messenger)
+{
+  if (value.find('\n') != std::string::npos) {
+    if (messenger) {
+      std::string message = "Value of ";
+      message += key;
+      message += " contained a newline; truncating";
+      messenger->IssueMessage(cmake::WARNING, message);
+    }
+
+    std::string comment = "WARNING: Value of ";
+    comment += key;
+    comment += " contained a newline and was truncated. Original value:";
+
+    OutputWarningComment(fout, comment, true);
+    OutputWarningComment(fout, value, false);
+  }
+}
+
 void cmCacheManager::RemoveCacheEntry(const std::string& key)
 void cmCacheManager::RemoveCacheEntry(const std::string& key)
 {
 {
   CacheEntryMap::iterator i = this->Cache.find(key);
   CacheEntryMap::iterator i = this->Cache.find(key);

+ 13 - 4
Source/cmCacheManager.h

@@ -15,7 +15,7 @@
 #include "cmPropertyMap.h"
 #include "cmPropertyMap.h"
 #include "cmStateTypes.h"
 #include "cmStateTypes.h"
 
 
-class cmake;
+class cmMessenger;
 
 
 /** \class cmCacheManager
 /** \class cmCacheManager
  * \brief Control class for cmake's cache
  * \brief Control class for cmake's cache
@@ -108,7 +108,7 @@ public:
                  std::set<std::string>& includes);
                  std::set<std::string>& includes);
 
 
   ///! Save cache for given makefile.  Saves to output path/CMakeCache.txt
   ///! Save cache for given makefile.  Saves to output path/CMakeCache.txt
-  bool SaveCache(const std::string& path);
+  bool SaveCache(const std::string& path, cmMessenger* messenger);
 
 
   ///! Delete the cache given
   ///! Delete the cache given
   bool DeleteCache(const std::string& path);
   bool DeleteCache(const std::string& path);
@@ -218,16 +218,25 @@ protected:
   unsigned int CacheMinorVersion;
   unsigned int CacheMinorVersion;
 
 
 private:
 private:
-  cmake* CMakeInstance;
   typedef std::map<std::string, CacheEntry> CacheEntryMap;
   typedef std::map<std::string, CacheEntry> CacheEntryMap;
   static void OutputHelpString(std::ostream& fout,
   static void OutputHelpString(std::ostream& fout,
                                const std::string& helpString);
                                const std::string& helpString);
+  static void OutputWarningComment(std::ostream& fout,
+                                   std::string const& message,
+                                   bool wrapSpaces);
+  static void OutputNewlineTruncationWarning(std::ostream& fout,
+                                             std::string const& key,
+                                             std::string const& value,
+                                             cmMessenger* messenger);
   static void OutputKey(std::ostream& fout, std::string const& key);
   static void OutputKey(std::ostream& fout, std::string const& key);
   static void OutputValue(std::ostream& fout, std::string const& value);
   static void OutputValue(std::ostream& fout, std::string const& value);
+  static void OutputValueNoNewlines(std::ostream& fout,
+                                    std::string const& value);
 
 
   static const char* PersistentProperties[];
   static const char* PersistentProperties[];
   bool ReadPropertyEntry(std::string const& key, CacheEntry& e);
   bool ReadPropertyEntry(std::string const& key, CacheEntry& e);
-  void WritePropertyEntries(std::ostream& os, CacheIterator i);
+  void WritePropertyEntries(std::ostream& os, CacheIterator i,
+                            cmMessenger* messenger);
 
 
   CacheEntryMap Cache;
   CacheEntryMap Cache;
   // Only cmake and cmState should be able to add cache values
   // Only cmake and cmState should be able to add cache values

+ 2 - 2
Source/cmState.cxx

@@ -107,9 +107,9 @@ bool cmState::LoadCache(const std::string& path, bool internal,
   return this->CacheManager->LoadCache(path, internal, excludes, includes);
   return this->CacheManager->LoadCache(path, internal, excludes, includes);
 }
 }
 
 
-bool cmState::SaveCache(const std::string& path)
+bool cmState::SaveCache(const std::string& path, cmMessenger* messenger)
 {
 {
-  return this->CacheManager->SaveCache(path);
+  return this->CacheManager->SaveCache(path, messenger);
 }
 }
 
 
 bool cmState::DeleteCache(const std::string& path)
 bool cmState::DeleteCache(const std::string& path)

+ 2 - 1
Source/cmState.h

@@ -23,6 +23,7 @@ class cmCacheManager;
 class cmCommand;
 class cmCommand;
 class cmPropertyDefinition;
 class cmPropertyDefinition;
 class cmStateSnapshot;
 class cmStateSnapshot;
+class cmMessenger;
 
 
 class cmState
 class cmState
 {
 {
@@ -59,7 +60,7 @@ public:
                  std::set<std::string>& excludes,
                  std::set<std::string>& excludes,
                  std::set<std::string>& includes);
                  std::set<std::string>& includes);
 
 
-  bool SaveCache(const std::string& path);
+  bool SaveCache(const std::string& path, cmMessenger* messenger);
 
 
   bool DeleteCache(const std::string& path);
   bool DeleteCache(const std::string& path);
 
 

+ 1 - 1
Source/cmake.cxx

@@ -1770,7 +1770,7 @@ bool cmake::LoadCache(const std::string& path, bool internal,
 
 
 bool cmake::SaveCache(const std::string& path)
 bool cmake::SaveCache(const std::string& path)
 {
 {
-  bool result = this->State->SaveCache(path);
+  bool result = this->State->SaveCache(path, this->GetMessenger());
   static const char* entries[] = { "CMAKE_CACHE_MAJOR_VERSION",
   static const char* entries[] = { "CMAKE_CACHE_MAJOR_VERSION",
                                    "CMAKE_CACHE_MINOR_VERSION",
                                    "CMAKE_CACHE_MINOR_VERSION",
                                    "CMAKE_CACHE_PATCH_VERSION",
                                    "CMAKE_CACHE_PATCH_VERSION",