CPack/NSIS: Fix matching of reserved component names

"Console" unexpectedly matches the reserved name regex.  This revealed
that `cmCPackNSISGenerator::CreateComponentDescription()` needs to use
the name returned by `GetSanitizedDirOrFileName()` for the component
file glob.

Fix the change from commit a1af593291 (CPack: Support arbitrary
component name when packaging, 2024-05-01, v3.30.0-rc1~151^2~1) to
address these issues and add related checks to the `CPackNSISGenerator`
test case.

Issue: #23612
This commit is contained in:
K. R. Walker 2024-08-19 12:00:18 -06:00 committed by Brad King
parent 97bb92ace5
commit b1f956529a
4 changed files with 45 additions and 3 deletions

View File

@ -1552,6 +1552,7 @@ std::string cmCPackGenerator::GetSanitizedDirOrFileName(
#ifdef _WIN32
// Given name matches a reserved name (on Windows)?
// Then return it prepended with an underscore.
// See https://learn.microsoft.com/en-us/windows/win32/fileio/naming-a-file
cmsys::RegularExpression reserved_pattern("^("
"[Cc][Oo][Nn]|"
"[Pp][Rr][Nn]|"
@ -1559,7 +1560,7 @@ std::string cmCPackGenerator::GetSanitizedDirOrFileName(
"[Nn][Uu][Ll]|"
"[Cc][Oo][Mm][1-9]|"
"[Ll][Pp][Tt][1-9]"
")([.].+)?");
")[.]?$");
if (reserved_pattern.find(name)) {
return "_" + name;
}

View File

@ -863,8 +863,8 @@ std::string cmCPackNSISGenerator::CreateComponentDescription(
/* clang-format on */
componentCode += out.str();
} else {
componentCode +=
" File /r \"${INST_DIR}\\" + component->Name + "\\*.*\"\n";
componentCode += " File /r \"${INST_DIR}\\" +
this->GetSanitizedDirOrFileName(component->Name) + "\\*.*\"\n";
}
componentCode += "SectionEnd\n";

View File

@ -10,6 +10,26 @@ install(TARGETS hello
LIBRARY DESTINATION .
BUNDLE DESTINATION .)
# Component that is a reserved name on Windows.
# See https://learn.microsoft.com/en-us/windows/win32/fileio/naming-a-file
install(
DIRECTORY .
DESTINATION txt
COMPONENT CON
FILES_MATCHING PATTERN *.txt)
# Component name that is similar to a reserved name on Windows.
install(
DIRECTORY .
DESTINATION txt
COMPONENT Console
FILES_MATCHING PATTERN *.txt)
# Component name that is strongly discouraged on Windows.
install(
DIRECTORY .
DESTINATION txt
COMPONENT EndsWithDot.
FILES_MATCHING PATTERN *.txt)
set(CPACK_NSIS_MUI_HEADERIMAGE "${PROJECT_SOURCE_DIR}\\\\header-image.bmp")
set(CPACK_PACKAGE_ICON "${PROJECT_SOURCE_DIR}\\\\header-icon.bmp")
set(CPACK_NSIS_MUI_ICON "${PROJECT_SOURCE_DIR}\\\\install.ico")

View File

@ -69,3 +69,24 @@ if("${output_index}" EQUAL "-1")
else()
message(FATAL_ERROR "License found in the project")
endif()
file(STRINGS "${project_file}" line REGEX [[\\_CON\\]])
string(FIND "${line}" [[\_CON\]] output_index)
message(STATUS "Found CON component reserved directory name as _CON")
if("${output_index}" EQUAL "-1")
message(FATAL_ERROR "CON component reserved directory name not found as _CON in the project")
endif()
file(STRINGS "${project_file}" line REGEX [[\\Console\\]])
string(FIND "${line}" [[\Console\]] output_index)
message(STATUS "Found Console component directory name as Console")
if("${output_index}" EQUAL "-1")
message(FATAL_ERROR "Console component directory name not found as Console in the project")
endif()
file(STRINGS "${project_file}" line REGEX [[\\EndsWithDot._\\]])
string(FIND "${line}" [[\EndsWithDot._\]] output_index)
message(STATUS "Found EndsWithDot. component directory name as EndsWithDot._")
if("${output_index}" EQUAL "-1")
message(FATAL_ERROR "EndsWithDot. component directory name not found as EndsWithDot._ in the project")
endif()