From 9d0604149e0fe8ddd24109fa4ef0d8ec670629f5 Mon Sep 17 00:00:00 2001 From: Ilya Dryomov Date: Sun, 29 Nov 2015 21:46:41 +0100 Subject: [PATCH] rbd: bail if too many arguments provided The code has a catch clause for that, but it was being rendered useless by the preceding if (command_spec.size() > matching_spec->size()) positional_options.add(at::POSITIONAL_ARGUMENTS.c_str(), -1); which names all (both expected and extraneous) positional arguments. Change it to name only expected arguments, deriving the number of expected arguments from the length of positional_opts vector, supplied by each action. This works for all actions except "feature enable" and "feature disable" which are specified as multitoken, so keep on passing in -1 for those. Signed-off-by: Ilya Dryomov --- src/test/cli/rbd/too-many-args.t | 33 ++++++++++++++++++++++++++++++++ src/tools/rbd/Shell.cc | 11 +++++++---- 2 files changed, 40 insertions(+), 4 deletions(-) create mode 100644 src/test/cli/rbd/too-many-args.t diff --git a/src/test/cli/rbd/too-many-args.t b/src/test/cli/rbd/too-many-args.t new file mode 100644 index 0000000000000..957845c277536 --- /dev/null +++ b/src/test/cli/rbd/too-many-args.t @@ -0,0 +1,33 @@ +A command taking no args: + + $ rbd showmapped junk + rbd: too many arguments + [1] + +A command taking one arg: + + $ rbd info img1 junk + rbd: too many arguments + [1] + +A command taking two args: + + $ rbd copy img1 img2 junk + rbd: too many arguments + [1] + +A command taking three args: + + $ rbd lock remove img1 lock1 locker1 junk + rbd: too many arguments + [1] + +A command taking unlimited args: + + $ rbd feature enable img1 layering striping exclusive-lock object-map fast-diff deep-flatten journaling junk + rbd: the argument for option is invalid + [1] + + $ rbd feature disable img1 layering striping exclusive-lock object-map fast-diff deep-flatten journaling junk + rbd: the argument for option is invalid + [1] diff --git a/src/tools/rbd/Shell.cc b/src/tools/rbd/Shell.cc index b9ea05b6a18b9..3e2987bd7e06b 100644 --- a/src/tools/rbd/Shell.cc +++ b/src/tools/rbd/Shell.cc @@ -123,8 +123,11 @@ int Shell::execute(int arg_count, const char **arg_values) { po::positional_options_description positional_options; positional_options.add(at::POSITIONAL_COMMAND_SPEC.c_str(), matching_spec->size()); - if (command_spec.size() > matching_spec->size()) { - positional_options.add(at::POSITIONAL_ARGUMENTS.c_str(), -1); + if (!positional_opts.options().empty()) { + int max_count = positional_opts.options().size(); + if (positional_opts.options().back()->semantic()->max_tokens() > 1) + max_count = -1; + positional_options.add(at::POSITIONAL_ARGUMENTS.c_str(), max_count); } po::options_description global_opts; @@ -156,8 +159,8 @@ int Shell::execute(int arg_count, const char **arg_values) { std::cerr << "rbd: " << e.what() << std::endl; return EXIT_FAILURE; } catch (po::too_many_positional_options_error& e) { - std::cerr << "rbd: too many positional arguments or unrecognized optional " - << "argument" << std::endl; + std::cerr << "rbd: too many arguments" << std::endl; + return EXIT_FAILURE; } catch (po::error& e) { std::cerr << "rbd: " << e.what() << std::endl; return EXIT_FAILURE; -- 2.39.5