cmCacheManager: Prevent corruption from multiline help strings

Corruption happens when a multiline help string starts with
a newline. This causes an overflow in substr() and the whole,
unescaped help string is written to the cache file.

Multiline strings are escaped line by line. The fix is to start
searching for line break points from position 1. A break point
at zero, which triggers the overflow, could only produce
a redundant empty line.

Fixes: #9098
This commit is contained in:
Nikita Nemkin
2025-02-04 22:04:35 +05:00
parent 8dfb1f40b7
commit 637a0f7ed4
3 changed files with 28 additions and 1 deletions

View File

@@ -414,7 +414,7 @@ void cmCacheManager::OutputHelpString(std::ostream& fout,
}
std::string oneLine;
std::string::size_type pos = 0;
for (std::string::size_type i = 0; i <= end; i++) {
for (std::string::size_type i = 1; i <= end; i++) {
if ((i == end) || (helpString[i] == '\n') ||
((i - pos >= 60) && (helpString[i] == ' '))) {
fout << "//";

View File

@@ -0,0 +1,21 @@
# Various newline possibilities
set(help_strings
"\n"
"\n\n\n"
"\n \n"
"\nline1"
"line1\n"
"\nline1\n"
"line1\nline2\nline3"
"\nline1\nline2\nline3\n"
"
line line line line line line line line line line line line line line line line
line line line line line line line line line line line line line line line line
line line line line line line line line line line line line line line line line"
)
foreach(help IN LISTS help_strings)
string(SHA1 name "${help}")
set("${name}" "" CACHE STRING "${help}" FORCE)
endforeach()

View File

@@ -64,6 +64,12 @@ if(NOT RunCMake_GENERATOR MATCHES "^Ninja Multi-Config$")
run_cmake(NoCMAKE_DEFAULT_CONFIGS)
endif()
block()
run_cmake(CacheVarHelpString)
set(RunCMake_TEST_NO_CLEAN 1)
run_cmake(CacheVarHelpString)
endblock()
if(NOT CMAKE_HOST_WIN32)
block()
# Test a non-writable build directory.