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 <idryomov@gmail.com>
This commit is contained in:
Ilya Dryomov 2015-11-29 21:46:41 +01:00
parent d133f423c8
commit 9d0604149e
2 changed files with 40 additions and 4 deletions

View File

@ -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]

View File

@ -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;