Commit eba619fc682d761bbcac7432c6930a78310901d9

Authored by Philip Top
Committed by GitHub
1 parent 81555321

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
@@ -247,3 +247,8 @@ set_property(TEST retired_deprecated PROPERTY PASS_REGULAR_EXPRESSION &quot;deprecate @@ -247,3 +247,8 @@ set_property(TEST retired_deprecated PROPERTY PASS_REGULAR_EXPRESSION &quot;deprecate
247 add_cli_exe(custom_parse custom_parse.cpp) 247 add_cli_exe(custom_parse custom_parse.cpp)
248 add_test(NAME cp_test COMMAND custom_parse --dv 1.7) 248 add_test(NAME cp_test COMMAND custom_parse --dv 1.7)
249 set_property(TEST cp_test PROPERTY PASS_REGULAR_EXPRESSION "called correct") 249 set_property(TEST cp_test PROPERTY PASS_REGULAR_EXPRESSION "called correct")
  250 +
  251 +#------------------------------------------------
  252 +# This executable is for manual testing and is expected to change regularly
  253 +
  254 +add_cli_exe(tester testEXE.cpp)
examples/testEXE.cpp 0 → 100644
  1 +// Copyright (c) 2017-2021, University of Cincinnati, developed by Henry Schreiner
  2 +// under NSF AWARD 1414736 and by the respective contributors.
  3 +// All rights reserved.
  4 +//
  5 +// SPDX-License-Identifier: BSD-3-Clause
  6 +
  7 +// Code modified from https://github.com/CLIUtils/CLI11/issues/559
  8 +
  9 +#include <CLI/CLI.hpp>
  10 +#include <iostream>
  11 +#include <string>
  12 +
  13 +int main(int argc, const char *argv[]) {
  14 +
  15 + int logLevel{0};
  16 + CLI::App app{"Test App"};
  17 +
  18 + app.add_option("-v", logLevel, "level");
  19 +
  20 + auto subcom = app.add_subcommand("sub", "")->fallthrough();
  21 + subcom->preparse_callback([&app](size_t) { app.get_subcommand("sub")->add_option_group("group"); });
  22 +
  23 + CLI11_PARSE(app, argc, argv);
  24 +
  25 + std::cout << "level: " << logLevel << std::endl;
  26 +}
include/CLI/App.hpp
@@ -2732,13 +2732,16 @@ class App { @@ -2732,13 +2732,16 @@ class App {
2732 } 2732 }
2733 } 2733 }
2734 } 2734 }
2735 - // If a subcommand, try the main command  
2736 - if(parent_ != nullptr && fallthrough_)  
2737 - return _get_fallthrough_parent()->_parse_arg(args, current_type);  
2738 - // don't capture missing if this is a nameless subcommand 2735 +
  2736 + // don't capture missing if this is a nameless subcommand and nameless subcommands can't fallthrough
2739 if(parent_ != nullptr && name_.empty()) { 2737 if(parent_ != nullptr && name_.empty()) {
2740 return false; 2738 return false;
2741 } 2739 }
  2740 +
  2741 + // If a subcommand, try the main command
  2742 + if(parent_ != nullptr && fallthrough_)
  2743 + return _get_fallthrough_parent()->_parse_arg(args, current_type);
  2744 +
2742 // Otherwise, add to missing 2745 // Otherwise, add to missing
2743 args.pop_back(); 2746 args.pop_back();
2744 _move_to_missing(current_type, current); 2747 _move_to_missing(current_type, current);