Browse Source

find_package: Ensure root path stack and module vars are restored

Fixes: #24595
Craig Scott 2 years ago
parent
commit
716ce4402a
2 changed files with 55 additions and 12 deletions
  1. 50 12
      Source/cmFindPackageCommand.cxx
  2. 5 0
      Source/cmFindPackageCommand.h

+ 50 - 12
Source/cmFindPackageCommand.cxx

@@ -456,6 +456,51 @@ int parseVersion(const std::string& version, unsigned int& major,
 
 } // anonymous namespace
 
+class cmFindPackageCommand::FlushDebugBufferOnExit
+{
+  cmFindPackageCommand& Command;
+
+public:
+  FlushDebugBufferOnExit(cmFindPackageCommand& command)
+    : Command(command)
+  {
+  }
+  ~FlushDebugBufferOnExit()
+  {
+    if (!Command.DebugBuffer.empty()) {
+      Command.DebugMessage(Command.DebugBuffer);
+    }
+  }
+};
+
+class cmFindPackageCommand::PushPopRootPathStack
+{
+  cmFindPackageCommand& Command;
+
+public:
+  PushPopRootPathStack(cmFindPackageCommand& command)
+    : Command(command)
+  {
+    Command.PushFindPackageRootPathStack();
+  }
+  ~PushPopRootPathStack() { Command.PopFindPackageRootPathStack(); }
+};
+
+class cmFindPackageCommand::SetRestoreFindDefinitions
+{
+  cmFindPackageCommand& Command;
+
+public:
+  SetRestoreFindDefinitions(
+    cmFindPackageCommand& command, const std::string& components,
+    const std::vector<std::pair<std::string, const char*>>& componentVarDefs)
+    : Command(command)
+  {
+    Command.SetModuleVariables(components, componentVarDefs);
+  }
+  ~SetRestoreFindDefinitions() { Command.RestoreFindDefinitions(); }
+};
+
 cmFindPackageCommand::PathLabel
   cmFindPackageCommand::PathLabel::PackageRedirect("PACKAGE_REDIRECT");
 cmFindPackageCommand::PathLabel cmFindPackageCommand::PathLabel::UserRegistry(
@@ -992,9 +1037,11 @@ bool cmFindPackageCommand::InitialPass(std::vector<std::string> const& args)
     }
   }
 
-  this->PushFindPackageRootPathStack();
-
-  this->SetModuleVariables(components, componentVarDefs);
+  // RAII objects to ensure we leave this function with consistent state
+  FlushDebugBufferOnExit flushDebugBufferOnExit(*this);
+  PushPopRootPathStack pushPopRootPathStack(*this);
+  SetRestoreFindDefinitions setRestoreFindDefinitions(*this, components,
+                                                      componentVarDefs);
 
   // See if we have been told to delegate to FetchContent or some other
   // redirected config package first. We have to check all names that
@@ -1115,15 +1162,6 @@ bool cmFindPackageCommand::InitialPass(std::vector<std::string> const& args)
 
   this->AppendSuccessInformation();
 
-  // Restore original state of "_FIND_" variables set in SetModuleVariables()
-  this->RestoreFindDefinitions();
-
-  this->PopFindPackageRootPathStack();
-
-  if (!this->DebugBuffer.empty()) {
-    this->DebugMessage(this->DebugBuffer);
-  }
-
   return loadedPackage;
 }
 

+ 5 - 0
Source/cmFindPackageCommand.h

@@ -105,6 +105,8 @@ private:
   void AddFindDefinition(const std::string& var, cm::string_view value);
   void RestoreFindDefinitions();
 
+  class SetRestoreFindDefinitions;
+
   enum /*class*/ HandlePackageModeType
   {
     Module,
@@ -127,6 +129,7 @@ private:
 
   void PushFindPackageRootPathStack();
   void PopFindPackageRootPathStack();
+  class PushPopRootPathStack;
 
   void ComputePrefixes();
   void FillPrefixesPackageRedirect();
@@ -215,6 +218,8 @@ private:
   std::set<std::string> IgnoredPrefixPaths;
   std::string DebugBuffer;
 
+  class FlushDebugBufferOnExit;
+
   /*! the selected sortOrder (None by default)*/
   SortOrderType SortOrder = None;
   /*! the selected sortDirection (Asc by default)*/