From d9748d753f34a030ee483e7723037ec4d335fae3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Mi=C4=85sko?= Date: Mon, 12 Nov 2018 00:00:00 +0000 Subject: bin: Consistently validate the number of arguments --- bin/dconf-dump.vala | 8 +++++ bin/dconf.vala | 38 ++++++++++++++++++++++ tests/test-dconf.py | 91 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 137 insertions(+) diff --git a/bin/dconf-dump.vala b/bin/dconf-dump.vala index d63e3eb..26f62d0 100644 --- a/bin/dconf-dump.vala +++ b/bin/dconf-dump.vala @@ -39,6 +39,10 @@ void dconf_dump (string[] args) throws Error { DConf.verify_dir (dir); + if (args[3] != null) { + throw new OptionError.FAILED ("too many arguments"); + } + add_to_keyfile (kf, client, dir); print ("%s", kf.to_data ()); } @@ -62,6 +66,10 @@ void dconf_load (string[] args) throws Error { var dir = args[2]; DConf.verify_dir (dir); + if (args[3] != null) { + throw new OptionError.FAILED ("too many arguments"); + } + var changeset = new DConf.Changeset (); var kf = keyfile_from_stdin (); diff --git a/bin/dconf.vala b/bin/dconf.vala index 8b0f211..1f0109c 100644 --- a/bin/dconf.vala +++ b/bin/dconf.vala @@ -173,6 +173,10 @@ void dconf_read (string?[] args) throws Error { DConf.verify_key (key); + if (args[index + 1] != null) { + throw new OptionError.FAILED ("too many arguments"); + } + var result = client.read_full (key, flags, null); if (result != null) { @@ -200,6 +204,10 @@ void dconf_list_locks (string?[] args) throws Error { DConf.verify_dir (dir); + if (args[3] != null) { + throw new OptionError.FAILED ("too many arguments"); + } + foreach (var item in client.list_locks (dir)) { print ("%s\n", item); } @@ -208,10 +216,21 @@ void dconf_list_locks (string?[] args) throws Error { void dconf_write (string?[] args) throws Error { var client = new DConf.Client (); var key = args[2]; + if (key == null) { + throw new OptionError.FAILED ("key not specified"); + } + var val = args[3]; + if (val == null) { + throw new OptionError.FAILED ("value not specified"); + } DConf.verify_key (key); + if (args[4] != null) { + throw new OptionError.FAILED ("too many arguments"); + } + client.write_sync (key, Variant.parse (null, val)); } @@ -229,6 +248,10 @@ void dconf_reset (string?[] args) throws Error { DConf.verify_path (path); + if (args[index + 1] != null) { + throw new OptionError.FAILED ("too many arguments"); + } + if (DConf.is_dir (path) && !force) { throw new OptionError.FAILED ("-f must be given to (recursively) reset entire dirs"); } @@ -259,6 +282,10 @@ void dconf_watch (string?[] args) throws Error { DConf.verify_path (path); + if (args[3] != null) { + throw new OptionError.FAILED ("too many arguments"); + } + client.changed.connect (watch_function); client.watch_sync (path); @@ -274,7 +301,18 @@ void dconf_blame (string?[] args) throws Error { void dconf_complete (string[] args) throws Error { var suffix = args[2]; + if (suffix == null) { + throw new OptionError.FAILED ("suffix not specified"); + } + var path = args[3]; + if (path == null) { + throw new OptionError.FAILED ("path not specified"); + } + + if (args[4] != null) { + throw new OptionError.FAILED ("too many arguments"); + } if (path == "") { print ("/\n"); diff --git a/tests/test-dconf.py b/tests/test-dconf.py index cc31ef2..e7ff747 100755 --- a/tests/test-dconf.py +++ b/tests/test-dconf.py @@ -147,6 +147,97 @@ class DBusTest(unittest.TestCase): self.temporary_dir.cleanup() + def test_invalid_usage(self): + """Invalid dconf usage results in non-zero exit code and help message. + """ + cases = [ + # No command: + [], + + # Invalid command: + ['no-such-command'], + + # Too many arguments: + ['blame', 'a'], + + # Missing arguments: + ['compile'], + ['compile', 'output'], + # Too many arguments: + ['compile', 'output', 'dir1', 'dir2'], + + # Missing arguments: + ['_complete'], + ['_complete', ''], + # Too many arguments: + ['_complete', '', '/', '/'], + + # Missing argument: + ['dump'], + # Dir is required: + ['dump', '/key'], + # Too many arguments: + ['dump', '/a/', '/b/'], + + # Missing argument: + ['list'], + # Dir is required: + ['list', '/foo/bar'], + # Too many arguments: + ['list', '/foo', '/bar'], + + # Missing argument: + ['list-locks'], + # Dir is required: + ['list-locks', '/key'], + # Too many arguments: + ['list-locks', '/a/', '/b/'], + + # Missing argument: + ['load'], + # Dir is required: + ['load', '/key'], + # Too many arguments: + ['load', '/a/', '/b/'], + + # Missing argument: + ['read'], + # Key is required: + ['read', '/dir/'], + # Too many arguments: + ['read', '/a', '/b'], + ['read', '-d', '/a', '/b'], + + # Missing arguments: + ['reset'], + # Invalid path: + ['reset', 'test/test'], + # Too many arguments: + ['reset', '/test', '/test'], + ['reset', '-f', '/', '/'], + + # Missing arguments: + ['watch'], + # Invalid path: + ['watch', 'foo'], + # Too many arguments: + ['watch', '/a', '/b'], + + # Missing arguments: + ['write'], + ['write', '/key'], + # Invalid value: + ['write', '/key', 'not-a-gvariant-value'], + # Too many arguments: + ['write', '/key', '1', '2'], + ] + + for args in cases: + with self.subTest(args=args): + with self.assertRaises(subprocess.CalledProcessError) as cm: + dconf(*args, stderr=subprocess.PIPE) + self.assertRegex(cm.exception.stderr, 'Usage:') + def test_read_nonexisiting(self): """Reading missing key produces no output. """ -- cgit v1.2.1