From 7ebd876f9f0fc94b0e3795ab79755009e783eee2 Mon Sep 17 00:00:00 2001 From: Michael Hanselmann <hansmi@google.com> Date: Tue, 11 Jan 2011 12:39:01 +0100 Subject: [PATCH] utils: Move more text-related code Signed-off-by: Michael Hanselmann <hansmi@google.com> Reviewed-by: Iustin Pop <iustin@google.com> --- lib/utils/__init__.py | 44 ------------------------------ lib/utils/text.py | 44 ++++++++++++++++++++++++++++++ test/ganeti.utils.text_unittest.py | 16 +++++++++++ test/ganeti.utils_unittest.py | 16 ----------- 4 files changed, 60 insertions(+), 60 deletions(-) diff --git a/lib/utils/__init__.py b/lib/utils/__init__.py index f31d52909..d808ce44d 100644 --- a/lib/utils/__init__.py +++ b/lib/utils/__init__.py @@ -73,9 +73,6 @@ _VALID_SERVICE_NAME_RE = re.compile("^[-_.a-zA-Z0-9]{1,128}$") UUID_RE = re.compile('^[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-' '[a-f0-9]{4}-[a-f0-9]{12}$') -#: Shell param checker regexp -_SHELLPARAM_REGEX = re.compile(r"^[-a-zA-Z0-9._+/:%@]+$") - def ForceDictType(target, key_types, allowed_values=None): """Force the values of a dict to have certain types. @@ -232,47 +229,6 @@ def TryConvert(fn, val): return nv -def IsValidShellParam(word): - """Verifies is the given word is safe from the shell's p.o.v. - - This means that we can pass this to a command via the shell and be - sure that it doesn't alter the command line and is passed as such to - the actual command. - - Note that we are overly restrictive here, in order to be on the safe - side. - - @type word: str - @param word: the word to check - @rtype: boolean - @return: True if the word is 'safe' - - """ - return bool(_SHELLPARAM_REGEX.match(word)) - - -def BuildShellCmd(template, *args): - """Build a safe shell command line from the given arguments. - - This function will check all arguments in the args list so that they - are valid shell parameters (i.e. they don't contain shell - metacharacters). If everything is ok, it will return the result of - template % args. - - @type template: str - @param template: the string holding the template for the - string formatting - @rtype: str - @return: the expanded command line - - """ - for word in args: - if not IsValidShellParam(word): - raise errors.ProgrammerError("Shell argument '%s' contains" - " invalid characters" % word) - return template % args - - def ParseCpuMask(cpu_mask): """Parse a CPU mask definition and return the list of CPU IDs. diff --git a/lib/utils/text.py b/lib/utils/text.py index af42d3680..c51d7292c 100644 --- a/lib/utils/text.py +++ b/lib/utils/text.py @@ -40,6 +40,9 @@ _SHELL_UNQUOTED_RE = re.compile('^[-.,=:/_+@A-Za-z0-9]+$') #: MAC checker regexp _MAC_CHECK_RE = re.compile("^([0-9a-f]{2}:){5}[0-9a-f]{2}$", re.I) +#: Shell param checker regexp +_SHELLPARAM_REGEX = re.compile(r"^[-a-zA-Z0-9._+/:%@]+$") + def MatchNameComponent(key, name_list, case_sensitive=True): """Try to match a name against a list. @@ -442,3 +445,44 @@ class LineSplitter: self.flush() if self._buffer: self._line_fn(self._buffer) + + +def IsValidShellParam(word): + """Verifies is the given word is safe from the shell's p.o.v. + + This means that we can pass this to a command via the shell and be + sure that it doesn't alter the command line and is passed as such to + the actual command. + + Note that we are overly restrictive here, in order to be on the safe + side. + + @type word: str + @param word: the word to check + @rtype: boolean + @return: True if the word is 'safe' + + """ + return bool(_SHELLPARAM_REGEX.match(word)) + + +def BuildShellCmd(template, *args): + """Build a safe shell command line from the given arguments. + + This function will check all arguments in the args list so that they + are valid shell parameters (i.e. they don't contain shell + metacharacters). If everything is ok, it will return the result of + template % args. + + @type template: str + @param template: the string holding the template for the + string formatting + @rtype: str + @return: the expanded command line + + """ + for word in args: + if not IsValidShellParam(word): + raise errors.ProgrammerError("Shell argument '%s' contains" + " invalid characters" % word) + return template % args diff --git a/test/ganeti.utils.text_unittest.py b/test/ganeti.utils.text_unittest.py index 9af51b390..2bc0c23b4 100755 --- a/test/ganeti.utils.text_unittest.py +++ b/test/ganeti.utils.text_unittest.py @@ -422,5 +422,21 @@ class TestLineSplitter(unittest.TestCase): "", "x"]) +class TestIsValidShellParam(unittest.TestCase): + def test(self): + for val, result in [ + ("abc", True), + ("ab;cd", False), + ]: + self.assertEqual(utils.IsValidShellParam(val), result) + + +class TestBuildShellCmd(unittest.TestCase): + def test(self): + self.assertRaises(errors.ProgrammerError, utils.BuildShellCmd, + "ls %s", "ab;cd") + self.assertEqual(utils.BuildShellCmd("ls %s", "ab"), "ls ab") + + if __name__ == "__main__": testutils.GanetiTestProgram() diff --git a/test/ganeti.utils_unittest.py b/test/ganeti.utils_unittest.py index 661be9a02..84c96c764 100755 --- a/test/ganeti.utils_unittest.py +++ b/test/ganeti.utils_unittest.py @@ -305,21 +305,5 @@ class TestTryConvert(unittest.TestCase): self.assertEqual(utils.TryConvert(fn, src), result) -class TestIsValidShellParam(unittest.TestCase): - def test(self): - for val, result in [ - ("abc", True), - ("ab;cd", False), - ]: - self.assertEqual(utils.IsValidShellParam(val), result) - - -class TestBuildShellCmd(unittest.TestCase): - def test(self): - self.assertRaises(errors.ProgrammerError, utils.BuildShellCmd, - "ls %s", "ab;cd") - self.assertEqual(utils.BuildShellCmd("ls %s", "ab"), "ls ab") - - if __name__ == '__main__': testutils.GanetiTestProgram() -- GitLab