Browse Source

add_custom_{command,target}: Fix crash on empty expanded command

Our custom command generation logic assumes that all command lines have
at least `argv0`.  In `add_custom_{command,target}` we already check
that at least a `COMMAND` was given, but using `COMMAND_EXPAND_LISTS` in
combination with a generator expression that expands to an empty string
may produce an empty command line.  In this case simply add an empty
string as a command to maintain our internal invariant.

Fixes: #17993
Brad King 7 years ago
parent
commit
6e59491659

+ 8 - 0
Source/cmCustomCommandGenerator.cxx

@@ -40,6 +40,14 @@ cmCustomCommandGenerator::cmCustomCommandGenerator(cmCustomCommand const& cc,
         argv.push_back(std::move(parsed_arg));
       }
     }
+
+    // Later code assumes at least one entry exists, but expanding
+    // lists on an empty command may have left this empty.
+    // FIXME: Should we define behavior for removing empty commands?
+    if (argv.empty()) {
+      argv.push_back(std::string());
+    }
+
     this->CommandLines.push_back(std::move(argv));
   }
 

+ 1 - 0
Tests/RunCMake/add_custom_target/CommandExpandsEmpty.cmake

@@ -0,0 +1 @@
+add_custom_target(EmptyCustom COMMAND "" COMMAND_EXPAND_LISTS)

+ 1 - 0
Tests/RunCMake/add_custom_target/RunCMakeTest.cmake

@@ -1,5 +1,6 @@
 include(RunCMake)
 
+run_cmake(CommandExpandsEmpty)
 run_cmake(NoArguments)
 run_cmake(BadTargetName)
 run_cmake(ByproductsNoCommand)