From 88f90a72f11bfdd16da63681ba3a5c482cf07304 Mon Sep 17 00:00:00 2001 From: Evan Wilde Date: Mon, 7 Aug 2023 11:14:14 -0700 Subject: file(GENERATE): Restore INPUT|CONTENT parse checking Refactoring in commit bff468c988 (cmFileCommand: Use cm::optional for keyword argument presence, 2022-06-30, v3.25.0-rc1~512^2) accidentally broke the check that the input argument is either `INPUT` or `CONTENT`. The check is supposed to fail when arguments are passed in the wrong order. For example: file(GENERATE OUTPUT ... TARGET CONTENT ) Prior to this fix, the input method would be CONTENT, but because the first parsed keyword is not `CONTENT`, `inputIsContent` would be false. The first parsed keyword isn't INPUT either, so we would not continue into the error condition. CMake would then try to handle this as an input file, when there isn't one, resulting in uninitialized memory usage and segfaults or corruption later on. Fixes: #25169 --- Source/cmFileCommand.cxx | 3 ++- Tests/RunCMake/File_Generate/OutOfOrderArgs-result.txt | 1 + Tests/RunCMake/File_Generate/OutOfOrderArgs-stderr.txt | 4 ++++ Tests/RunCMake/File_Generate/OutOfOrderArgs.cmake | 4 ++++ Tests/RunCMake/File_Generate/RunCMakeTest.cmake | 1 + 5 files changed, 12 insertions(+), 1 deletion(-) create mode 100644 Tests/RunCMake/File_Generate/OutOfOrderArgs-result.txt create mode 100644 Tests/RunCMake/File_Generate/OutOfOrderArgs-stderr.txt create mode 100644 Tests/RunCMake/File_Generate/OutOfOrderArgs.cmake diff --git a/Source/cmFileCommand.cxx b/Source/cmFileCommand.cxx index 45fba8b..8f2ebf5 100644 --- a/Source/cmFileCommand.cxx +++ b/Source/cmFileCommand.cxx @@ -2555,8 +2555,9 @@ bool HandleGenerateCommand(std::vector const& args, return false; } const bool inputIsContent = arguments.ParsedKeywords[1] == "CONTENT"_s; - if (!inputIsContent && arguments.ParsedKeywords[1] == "INPUT") { + if (!inputIsContent && arguments.ParsedKeywords[1] != "INPUT") { status.SetError("Unknown argument to GENERATE subcommand."); + return false; } std::string const& input = inputIsContent ? *arguments.Content : *arguments.Input; diff --git a/Tests/RunCMake/File_Generate/OutOfOrderArgs-result.txt b/Tests/RunCMake/File_Generate/OutOfOrderArgs-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/File_Generate/OutOfOrderArgs-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/File_Generate/OutOfOrderArgs-stderr.txt b/Tests/RunCMake/File_Generate/OutOfOrderArgs-stderr.txt new file mode 100644 index 0000000..a3f5cd5 --- /dev/null +++ b/Tests/RunCMake/File_Generate/OutOfOrderArgs-stderr.txt @@ -0,0 +1,4 @@ +^CMake Error at OutOfOrderArgs\.cmake:[0-9]+ \(file\): + file Unknown argument to GENERATE subcommand\. +Call Stack \(most recent call first\): + CMakeLists\.txt:[0-9]+ \(include\)$ diff --git a/Tests/RunCMake/File_Generate/OutOfOrderArgs.cmake b/Tests/RunCMake/File_Generate/OutOfOrderArgs.cmake new file mode 100644 index 0000000..7f0578b --- /dev/null +++ b/Tests/RunCMake/File_Generate/OutOfOrderArgs.cmake @@ -0,0 +1,4 @@ +file(GENERATE OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/output.txt" + CONDITION 1 + CONTENT "CONTENT argument" + ) diff --git a/Tests/RunCMake/File_Generate/RunCMakeTest.cmake b/Tests/RunCMake/File_Generate/RunCMakeTest.cmake index 5a670ae..e601991 100644 --- a/Tests/RunCMake/File_Generate/RunCMakeTest.cmake +++ b/Tests/RunCMake/File_Generate/RunCMakeTest.cmake @@ -15,6 +15,7 @@ endif() run_cmake(EmptyCondition1) run_cmake(EmptyCondition2) run_cmake(BadCondition) +run_cmake(OutOfOrderArgs) run_cmake(DebugEvaluate) run_cmake(GenerateSource) run_cmake(InputAndContent) -- cgit v0.12