From eba619fc682d761bbcac7432c6930a78310901d9 Mon Sep 17 00:00:00 2001 From: Philip Top Date: Wed, 17 Nov 2021 21:44:10 -0800 Subject: [PATCH] fix: a potential stack overflow error (#665) * Fix a potential stack overflow error if nameless subcommands have fallthough * style: pre-commit.ci fixes Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> --- examples/CMakeLists.txt | 5 +++++ examples/testEXE.cpp | 26 ++++++++++++++++++++++++++ include/CLI/App.hpp | 11 +++++++---- 3 files changed, 38 insertions(+), 4 deletions(-) create mode 100644 examples/testEXE.cpp diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index d0d45c62..26747f06 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -247,3 +247,8 @@ set_property(TEST retired_deprecated PROPERTY PASS_REGULAR_EXPRESSION "deprecate add_cli_exe(custom_parse custom_parse.cpp) add_test(NAME cp_test COMMAND custom_parse --dv 1.7) set_property(TEST cp_test PROPERTY PASS_REGULAR_EXPRESSION "called correct") + +#------------------------------------------------ +# This executable is for manual testing and is expected to change regularly + +add_cli_exe(tester testEXE.cpp) diff --git a/examples/testEXE.cpp b/examples/testEXE.cpp new file mode 100644 index 00000000..51fc8eb6 --- /dev/null +++ b/examples/testEXE.cpp @@ -0,0 +1,26 @@ +// Copyright (c) 2017-2021, University of Cincinnati, developed by Henry Schreiner +// under NSF AWARD 1414736 and by the respective contributors. +// All rights reserved. +// +// SPDX-License-Identifier: BSD-3-Clause + +// Code modified from https://github.com/CLIUtils/CLI11/issues/559 + +#include +#include +#include + +int main(int argc, const char *argv[]) { + + int logLevel{0}; + CLI::App app{"Test App"}; + + app.add_option("-v", logLevel, "level"); + + auto subcom = app.add_subcommand("sub", "")->fallthrough(); + subcom->preparse_callback([&app](size_t) { app.get_subcommand("sub")->add_option_group("group"); }); + + CLI11_PARSE(app, argc, argv); + + std::cout << "level: " << logLevel << std::endl; +} diff --git a/include/CLI/App.hpp b/include/CLI/App.hpp index 23e4c3c8..06737e98 100644 --- a/include/CLI/App.hpp +++ b/include/CLI/App.hpp @@ -2732,13 +2732,16 @@ class App { } } } - // If a subcommand, try the main command - if(parent_ != nullptr && fallthrough_) - return _get_fallthrough_parent()->_parse_arg(args, current_type); - // don't capture missing if this is a nameless subcommand + + // don't capture missing if this is a nameless subcommand and nameless subcommands can't fallthrough if(parent_ != nullptr && name_.empty()) { return false; } + + // If a subcommand, try the main command + if(parent_ != nullptr && fallthrough_) + return _get_fallthrough_parent()->_parse_arg(args, current_type); + // Otherwise, add to missing args.pop_back(); _move_to_missing(current_type, current);