Commit eba619fc682d761bbcac7432c6930a78310901d9
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>
Showing
3 changed files
with
38 additions
and
4 deletions
examples/CMakeLists.txt
| @@ -247,3 +247,8 @@ set_property(TEST retired_deprecated PROPERTY PASS_REGULAR_EXPRESSION "deprecate | @@ -247,3 +247,8 @@ set_property(TEST retired_deprecated PROPERTY PASS_REGULAR_EXPRESSION "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); |