diff options
| author | Lexi Winter <lexi@le-fay.org> | 2025-06-23 19:21:23 +0100 |
|---|---|---|
| committer | Lexi Winter <lexi@le-fay.org> | 2025-06-23 19:21:23 +0100 |
| commit | 936c7d1293ba2ed01719c1656dd30842c6db5582 (patch) | |
| tree | 2d4b408b331e0a5270d99533a6c2a3cfb70ae7be | |
| parent | 661e46dc3c59775a9bf06506c0978fc93c2254f8 (diff) | |
| download | nihil-936c7d1293ba2ed01719c1656dd30842c6db5582.tar.gz nihil-936c7d1293ba2ed01719c1656dd30842c6db5582.tar.bz2 | |
command_map: don't crash on empty arguments
| -rw-r--r-- | nihil/command_map.ccm | 6 | ||||
| -rw-r--r-- | nihil/tests/command_map.cc | 14 |
2 files changed, 15 insertions, 5 deletions
diff --git a/nihil/command_map.ccm b/nihil/command_map.ccm index 5aeb7c8..279c43e 100644 --- a/nihil/command_map.ccm +++ b/nihil/command_map.ccm @@ -71,6 +71,9 @@ struct node { // Run the handler for this node. auto invoke(Context const &ctx, int argc, char **argv) const -> int { + if (argc == 0) + throw usage_error("incomplete command"); + // Look for a subcommand with argv[0]. auto it = commands.find(argv[0]); if (it == commands.end()) @@ -85,9 +88,6 @@ struct node { --argc; ++argv; - if (argc == 0) - throw usage_error("incomplete command"); - // Otherwise, continue recursing. return child.invoke(ctx, argc, argv); } diff --git a/nihil/tests/command_map.cc b/nihil/tests/command_map.cc index 75b6f0d..c8cd1a1 100644 --- a/nihil/tests/command_map.cc +++ b/nihil/tests/command_map.cc @@ -25,10 +25,20 @@ TEST_CASE("command_map: basic", "[command_map]") "cmd", "sub1", nullptr }; auto argv = const_cast<char **>(args.data()); - nihil::dispatch_command(0, args.size(), argv); + nihil::dispatch_command(0, args.size() - 1, argv); REQUIRE(cmd_sub1_called == true); } +TEST_CASE("command_map: no arguments", "[command_map]") +{ + auto args = std::vector<char const *>{ + nullptr + }; + auto argv = const_cast<char **>(args.data()); + REQUIRE_THROWS_AS(nihil::dispatch_command(0, args.size() - 1, argv), + nihil::usage_error); +} + TEST_CASE("command_map: unknown command", "[command_map]") { auto args = std::vector<char const *>{ @@ -36,6 +46,6 @@ TEST_CASE("command_map: unknown command", "[command_map]") }; auto argv = const_cast<char **>(args.data()); - REQUIRE_THROWS_AS(nihil::dispatch_command(0, args.size(), argv), + REQUIRE_THROWS_AS(nihil::dispatch_command(0, args.size() - 1, argv), nihil::usage_error); } |
