Browse Source

ExternalProject: Prevent URL list-splitting on special characters

If a URL contains special characters like parentheses and a few others,
they would previously have caused a foreach() call that iterates over the
URLs to parse those special characters as separate, unquoted arguments.
They would then have effectively split the list of URLs at unexpected places.
Prepare the arguments for the foreach() call by using use bracket syntax
to robustly handle any URLs that do have unescaped special characters.

Issue: #25148
Craig Scott 1 year ago
parent
commit
54cb65b197
2 changed files with 9 additions and 1 deletions
  1. 8 0
      Modules/ExternalProject.cmake
  2. 1 1
      Modules/ExternalProject/download.cmake.in

+ 8 - 0
Modules/ExternalProject.cmake

@@ -1525,6 +1525,14 @@ function(_ep_write_downloadfile_script
     message(FATAL_ERROR "LOCAL can't be empty")
   endif()
 
+  # REMOTE could contain special characters that parse as separate arguments.
+  # Things like parentheses are legitimate characters in a URL, but would be
+  # seen as the start of a new unquoted argument by the cmake language parser.
+  # Avoid those special cases by preparing quoted strings for direct inclusion
+  # in the foreach() call that iterates over the set of URLs in REMOTE.
+  set(REMOTE "[====[${REMOTE}]====]")
+  string(REPLACE ";" "]====] [====[" REMOTE "${REMOTE}")
+
   if(timeout)
     set(TIMEOUT_ARGS TIMEOUT ${timeout})
     set(TIMEOUT_MSG "${timeout} seconds")

+ 1 - 1
Modules/ExternalProject/download.cmake.in

@@ -107,7 +107,7 @@ foreach(i RANGE ${retry_number})
   if(status_code IN_LIST download_retry_codes)
     sleep_before_download(${i})
   endif()
-  foreach(url @REMOTE@)
+  foreach(url IN ITEMS @REMOTE@)
     if(NOT url IN_LIST skip_url_list)
       message(STATUS "Using src='${url}'")