]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
rbd: bail if too many arguments provided 6738/head
authorIlya Dryomov <idryomov@gmail.com>
Sun, 29 Nov 2015 20:46:41 +0000 (21:46 +0100)
committerIlya Dryomov <idryomov@gmail.com>
Mon, 30 Nov 2015 16:50:10 +0000 (17:50 +0100)
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>
src/test/cli/rbd/too-many-args.t [new file with mode: 0644]
src/tools/rbd/Shell.cc

diff --git a/src/test/cli/rbd/too-many-args.t b/src/test/cli/rbd/too-many-args.t
new file mode 100644 (file)
index 0000000..957845c
--- /dev/null
@@ -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]
index b9ea05b6a18b94e484624602326492d437aaf0a7..3e2987bd7e06b9a8baab78bb9e30f0837a4ba3a9 100644 (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;