Merge topic 'bin2c-fix-template-placeholder-args'

3a45596703 cmake -E bin2c: Fix segfault in template placeholder options

Acked-by: Kitware Robot <kwrobot@kitware.com>
Acked-by: buildbot <buildbot@kitware.com>
Merge-request: !11623
This commit is contained in:
Brad King 2026-01-24 12:57:24 +00:00 committed by Kitware Robot
commit 5f44fc5e2c
6 changed files with 37 additions and 20 deletions

View File

@ -690,9 +690,9 @@ struct CoCompileJob
struct Bin2CTemplateFile
{
std::string ArrayPlaceholder{ "array"_s };
std::string LengthPlaceholder{ "length"_s };
std::istream* TemplateStream = nullptr;
std::istream* TemplateStream;
cm::string_view ArrayPlaceholder;
cm::string_view LengthPlaceholder;
};
enum class Bin2CBase
@ -2146,51 +2146,43 @@ int cmcmd::ExecuteCMakeCommand(std::vector<std::string> const& args,
std::string inputFile = "-";
std::string outputFile = "-";
cm::optional<Bin2CTemplateFile> templateFile;
cm::optional<cm::string_view> templateFilename;
cm::optional<cm::string_view> templateArrayPlaceholder;
cm::optional<cm::string_view> templateLengthPlaceholder;
bool printTrailingComma = false;
bool printSigned = false;
auto base = Bin2CBase::Hex;
auto const ensureTemplateFile = [&templateFile]() -> Bin2CTemplateFile& {
if (!templateFile) {
templateFile.emplace();
}
return *templateFile;
};
using CommandArgument =
cmCommandLineArgument<bool(std::string const& value)>;
std::vector<CommandArgument> arguments = {
CommandArgument{ "--template-file", CommandArgument::Values::One,
[&ensureTemplateFile,
&templateFilename](std::string const& arg) -> bool {
ensureTemplateFile();
[&templateFilename](std::string const& arg) -> bool {
templateFilename = arg;
return true;
} },
CommandArgument{
"--template-array-placeholder", CommandArgument::Values::One,
[&ensureTemplateFile](std::string const& arg) -> bool {
[&templateArrayPlaceholder](std::string const& arg) -> bool {
if (arg.find_first_not_of(validPlaceholderChars) !=
std::string::npos) {
std::cerr << "Invalid array placeholder name: \"" << arg
<< "\"\n";
return false;
}
ensureTemplateFile().ArrayPlaceholder = arg;
templateArrayPlaceholder = arg;
return true;
} },
CommandArgument{
"--template-length-placeholder", CommandArgument::Values::One,
[&ensureTemplateFile](std::string const& arg) -> bool {
[&templateLengthPlaceholder](std::string const& arg) -> bool {
if (arg.find_first_not_of(validPlaceholderChars) !=
std::string::npos) {
std::cerr << "Invalid length placeholder name: \"" << arg
<< "\"\n";
return false;
}
ensureTemplateFile().LengthPlaceholder = arg;
templateLengthPlaceholder = arg;
return true;
} },
CommandArgument{ "--trailing-comma", CommandArgument::Values::Zero,
@ -2249,6 +2241,7 @@ int cmcmd::ExecuteCMakeCommand(std::vector<std::string> const& args,
i++;
}
cm::optional<Bin2CTemplateFile> templateFile;
cmsys::ifstream templateStream;
if (templateFilename) {
templateStream.open(templateFilename->data());
@ -2257,7 +2250,21 @@ int cmcmd::ExecuteCMakeCommand(std::vector<std::string> const& args,
<< *templateFilename << "\"\n";
return 1;
}
templateFile->TemplateStream = &templateStream;
templateFile =
Bin2CTemplateFile{ &templateStream,
templateArrayPlaceholder.value_or("array"_s),
templateLengthPlaceholder.value_or("length"_s) };
} else {
if (templateArrayPlaceholder) {
std::cerr << "Cannot use --template-array-placeholder without "
"--template-file\n\n";
return usage();
}
if (templateLengthPlaceholder) {
std::cerr << "Cannot use --template-length-placeholder without "
"--template-file\n\n";
return usage();
}
}
std::istream* sin = &std::cin;

View File

@ -43,7 +43,9 @@ file(WRITE "${RunCMake_TEST_BINARY_DIR}/not_a_dir" "")
run_cmake_command(output_not_a_dir ${CMAKE_COMMAND} -E bin2c "${RunCMake_TEST_BINARY_DIR}/basic.bin" "not_a_dir/output_not_a_dir.c.txt")
run_cmake_command(template_file_invalid_array_placeholder ${CMAKE_COMMAND} -E bin2c --template-file "${RunCMake_SOURCE_DIR}/template_file.c.in.txt" --template-array-placeholder "array*")
run_cmake_command(template_file_invalid_length_placeholder ${CMAKE_COMMAND} -E bin2c --template-file "${RunCMake_SOURCE_DIR}/template_file.c.in.txt" --template-length-placeholder "length*")
run_cmake_command(template_file_noexist ${CMAKE_COMMAND} -E bin2c --template-file noexist.c.in.txt a a)
run_cmake_command(template_array_placeholder_without_file ${CMAKE_COMMAND} -E bin2c --template-array-placeholder arr)
run_cmake_command(template_length_placeholder_without_file ${CMAKE_COMMAND} -E bin2c --template-length-placeholder len)
run_cmake_command(template_file_noexist ${CMAKE_COMMAND} -E bin2c --template-file noexist.c.in.txt)
run_cmake_command(template_file_double_array ${CMAKE_COMMAND} -E bin2c --template-file "${RunCMake_SOURCE_DIR}/template_file_double_array.c.in.txt" "${RunCMake_TEST_BINARY_DIR}/basic.bin")
run_cmake_command(template_file_length_before_array ${CMAKE_COMMAND} -E bin2c --template-file "${RunCMake_SOURCE_DIR}/template_file_length_before_array.c.in.txt" "${RunCMake_TEST_BINARY_DIR}/basic.bin")

View File

@ -0,0 +1,3 @@
^Cannot use --template-array-placeholder without --template-file
bin2c Usage: -E bin2c \[<options>\.\.\.\] \[--\] \[<input-file> \[<output-file>\]\]$

View File

@ -0,0 +1,3 @@
^Cannot use --template-length-placeholder without --template-file
bin2c Usage: -E bin2c \[<options>\.\.\.\] \[--\] \[<input-file> \[<output-file>\]\]$