From 5c74f942c47121a8e34d6817c2869a07cfb2e94f Mon Sep 17 00:00:00 2001 From: Olivier Mangin Date: Thu, 28 Sep 2017 17:34:32 -0400 Subject: [PATCH] [Fix #88] Adds proper escaping for arguments in alias plugin. --- pubs/p3.py | 3 +++ pubs/plugs/alias/alias.py | 8 +++++--- tests/test_plug_alias.py | 19 +++++++++++++++---- 3 files changed, 23 insertions(+), 7 deletions(-) diff --git a/pubs/p3.py b/pubs/p3.py index 9c9082c..3087627 100644 --- a/pubs/p3.py +++ b/pubs/p3.py @@ -28,6 +28,8 @@ if sys.version_info[0] == 2: ustdio.seek(0) return ustdio.read() + from pipes import quote as shell_quote + else: ustr = str uchr = chr @@ -52,6 +54,7 @@ else: return stdio.read() import pickle + from pipes import quote as shell_quote input = input diff --git a/pubs/plugs/alias/alias.py b/pubs/plugs/alias/alias.py index 7a75467..f99b9d3 100644 --- a/pubs/plugs/alias/alias.py +++ b/pubs/plugs/alias/alias.py @@ -1,6 +1,7 @@ import subprocess import shlex +from ...p3 import shell_quote from ...plugins import PapersPlugin from ...pubs_cmd import execute @@ -50,9 +51,10 @@ class ShellAlias(Alias): as shell arguments. """ subprocess.call( - 'papers_alias_fun () {{\n{}\n}}\npapers_alias_fun {}'.format( - self.definition, ' '.join(args.arguments)), - shell=True) + 'pubs_alias_fun () {{\n{}\n}}\npubs_alias_fun {}'.format( + self.definition, + ' '.join([shell_quote(a) for a in args.arguments]) + ), shell=True) class AliasPlugin(PapersPlugin): diff --git a/tests/test_plug_alias.py b/tests/test_plug_alias.py index c15b986..82b9215 100644 --- a/tests/test_plug_alias.py +++ b/tests/test_plug_alias.py @@ -1,3 +1,4 @@ +import shlex import unittest import dotdot @@ -8,10 +9,10 @@ from pubs.plugs.alias.alias import (Alias, AliasPlugin, CommandAlias, ShellAlias) -def to_args(arg_str): +def to_args(arg_strings): o = lambda: None # Dirty hack o.prog = 'pubs' - o.arguments = arg_str.split(' ') + o.arguments = arg_strings return o @@ -37,7 +38,7 @@ class AliasTestCase(unittest.TestCase): def testAlias(self): alias = Alias.create_alias('print', 'open -w lpppp') - alias.command(None, to_args('CiteKey')) + alias.command(None, to_args(['CiteKey'])) self.assertIsNone(self.subprocess.called) self.assertEqual(self.cmd_execute.executed, ['pubs', 'open', '-w', 'lpppp', 'CiteKey']) @@ -46,10 +47,20 @@ class AliasTestCase(unittest.TestCase): """This actually just test that subprocess.call is called. """ alias = Alias.create_alias('count', '!pubs list -k | wc -l') - alias.command(None, to_args('')) + alias.command(None, to_args([])) self.assertIsNone(self.cmd_execute.executed) self.assertIsNotNone(self.subprocess.called) + def testShellAliasEscapes(self): + alias = Alias.create_alias('count', '!echo "$@"') + args = ['a b c', "d,e f\""] + alias.command(None, to_args(args)) + self.assertIsNone(self.cmd_execute.executed) + self.assertIsNotNone(self.subprocess.called) + self.assertEqual( + shlex.split(self.subprocess.called.splitlines()[-1])[1:], + args) + class AliasPluginTestCase(unittest.TestCase):