diff options
author | Patrick Totzke <patricktotzke@gmail.com> | 2012-06-03 13:12:52 +0100 |
---|---|---|
committer | Patrick Totzke <patricktotzke@gmail.com> | 2012-06-03 13:16:40 +0100 |
commit | 716a777bd883de7e9b23caf659bf6876f835473b (patch) | |
tree | 8b894483a3b8419a18d939ca8d24f5bfaac5a2b6 /alot | |
parent | bec78df4a6932048f73c515d7c1ed9be98c98817 (diff) |
add helper split_commandstring
that splits a command string into a list of strings to pass on to subprocess.Popen and the like.
This helper is now used throughout the application instead of calling shlex.split directly as this
is a potential source for errors because shlex is not yet able to properly deal with unicode
bytestrings.
Diffstat (limited to 'alot')
-rw-r--r-- | alot/account.py | 4 | ||||
-rw-r--r-- | alot/addressbooks.py | 4 | ||||
-rw-r--r-- | alot/commands/__init__.py | 4 | ||||
-rw-r--r-- | alot/commands/globals.py | 10 | ||||
-rw-r--r-- | alot/commands/thread.py | 8 | ||||
-rw-r--r-- | alot/db/utils.py | 4 | ||||
-rw-r--r-- | alot/helper.py | 11 |
7 files changed, 26 insertions, 19 deletions
diff --git a/alot/account.py b/alot/account.py index b65bf3cb..29ec768b 100644 --- a/alot/account.py +++ b/alot/account.py @@ -4,9 +4,9 @@ import time import email import os import glob -import shlex from alot.helper import call_cmd_async +from alot.helper import split_commandstring import alot.crypto as crypto @@ -151,7 +151,7 @@ class SendmailAccount(Account): def send_mail(self, mail): mail['Date'] = email.utils.formatdate(time.time(), True) - cmdlist = shlex.split(self.cmd.encode('utf-8', errors='ignore')) + cmdlist = split_commandstring(self.cmd) def cb(out): logging.info('sent mail successfully') diff --git a/alot/addressbooks.py b/alot/addressbooks.py index f527492f..16818a39 100644 --- a/alot/addressbooks.py +++ b/alot/addressbooks.py @@ -1,9 +1,9 @@ import re import os -import shlex from alot.settings.utils import read_config from helper import call_cmd +from alot.helper import split_commandstring class AddressBook(object): @@ -73,7 +73,7 @@ class MatchSdtoutAddressbook(AddressBook): return self.lookup('\'\'') def lookup(self, prefix): - cmdlist = shlex.split(self.command.encode('utf-8', errors='ignore')) + cmdlist = split_commandstring(self.command) resultstring, errmsg, retval = call_cmd(cmdlist + [prefix]) if not resultstring: return [] diff --git a/alot/commands/__init__.py b/alot/commands/__init__.py index ff9b7951..b65af5e3 100644 --- a/alot/commands/__init__.py +++ b/alot/commands/__init__.py @@ -1,12 +1,12 @@ import os import re import glob -import shlex import logging import argparse from alot.settings import settings import alot.helper +from alot.helper import split_commandstring class Command(object): @@ -168,7 +168,7 @@ def commandfactory(cmdline, mode='global'): cmdline = 'shellescape \'%s\'' % cmdline[1:] cmdline = re.sub(r'"(.*)"', r'"\\"\1\\""', cmdline) try: - args = shlex.split(cmdline.encode('utf-8')) + args = split_commandstring(cmdline) except ValueError, e: raise CommandParseError(e.message) args = map(lambda x: alot.helper.string_decode(x, 'utf-8'), args) diff --git a/alot/commands/globals.py b/alot/commands/globals.py index bc1e779a..b8722185 100644 --- a/alot/commands/globals.py +++ b/alot/commands/globals.py @@ -2,7 +2,6 @@ import os import code from twisted.internet import threads import subprocess -import shlex import email import urwid from twisted.internet.defer import inlineCallbacks @@ -26,6 +25,7 @@ from alot.db.envelope import Envelope from alot import commands from alot.settings import settings from alot.errors import GPGProblem +from alot.helper import split_commandstring MODE = 'global' @@ -188,7 +188,7 @@ class ExternalCommand(Command): term_cmd = settings.get('terminal_cmd', '') term_cmd = term_cmd.encode('utf-8', errors='ignore') logging.info('spawn in terminal: %s' % term_cmd) - termcmdlist = shlex.split(term_cmd) + termcmdlist = split_commandstring(term_cmd) logging.info('term cmdlist: %s' % termcmdlist) self.cmdlist = termcmdlist + self.cmdlist @@ -251,11 +251,9 @@ class EditCommand(ExternalCommand): if '%s' in editor_cmdstring: cmdstring = editor_cmdstring.replace('%s', helper.shell_quote(path)) - cmdstring = cmdstring.encode('utf-8', errors='ignore') - self.cmdlist = shlex.split(cmdstring) + self.cmdlist = split_commandstring(cmdstring) else: - cmdstring = editor_cmdstring.encode('utf-8', errors='ignore') - self.cmdlist = shlex.split(cmdstring) + [path] + self.cmdlist = split_commandstring(editor_cmdstring) + [path] logging.debug(self.cmdlist) diff --git a/alot/commands/thread.py b/alot/commands/thread.py index c304fa0c..be6c10d4 100644 --- a/alot/commands/thread.py +++ b/alot/commands/thread.py @@ -2,7 +2,6 @@ import os import logging import tempfile from twisted.internet.defer import inlineCallbacks -import shlex import re import subprocess from email.Utils import parseaddr @@ -22,10 +21,10 @@ from alot.db.utils import extract_headers from alot.db.utils import extract_body from alot.db.envelope import Envelope from alot.db.attachment import Attachment - from alot.db.errors import DatabaseROError from alot.settings import settings from alot.helper import parse_mailcap_nametemplate +from alot.helper import split_commandstring MODE = 'thread' @@ -402,7 +401,7 @@ class PipeCommand(Command): """ Command.__init__(self, **kwargs) if isinstance(cmd, unicode): - cmd = shlex.split(cmd.encode('UTF-8')) + cmd = split_commandstring(cmd) self.cmd = cmd self.whole_thread = all self.separately = separately @@ -701,8 +700,7 @@ class OpenAttachmentCommand(Command): handler_cmd = mailcap.subst(handler_raw_commandstring, mimetype, filename=tempfile_name, plist=parms) - handler_cmd = handler_cmd.encode('utf-8', errors='ignore') - handler_cmdlist = shlex.split(handler_cmd) + handler_cmdlist = split_commandstring(handler_cmd) # 'needsterminal' makes handler overtake the terminal nt = entry.get('needsterminal', None) diff --git a/alot/db/utils.py b/alot/db/utils.py index 55073e45..e9d40c21 100644 --- a/alot/db/utils.py +++ b/alot/db/utils.py @@ -2,7 +2,6 @@ import os import email import tempfile import re -import shlex from email.header import Header import email.charset as charset charset.add_charset('utf-8', charset.QP, charset.QP, 'utf-8') @@ -15,6 +14,7 @@ from alot.settings import settings from alot.helper import string_sanitize from alot.helper import string_decode from alot.helper import parse_mailcap_nametemplate +from alot.helper import split_commandstring def extract_headers(mail, headers=None): @@ -99,7 +99,7 @@ def extract_body(mail, types=None): filename=tmpfile.name, plist=parms) logging.debug('command: %s' % cmd) logging.debug('parms: %s' % str(parms)) - cmdlist = shlex.split(cmd.encode('utf-8', errors='ignore')) + cmdlist = split_commandstring(cmd) # call handler rendered_payload, errmsg, retval = helper.call_cmd(cmdlist) # remove tempfile diff --git a/alot/helper.py b/alot/helper.py index 8d596994..f94e03f2 100644 --- a/alot/helper.py +++ b/alot/helper.py @@ -4,6 +4,7 @@ from datetime import datetime from collections import deque from string import strip import subprocess +import shlex import email import os import re @@ -21,6 +22,16 @@ import logging import tempfile +def split_commandstring(cmdstring): + """ + split command string into a list of strings to pass on to subprocess.Popen + and the like. This simply calls shlex.split but works also with unicode + bytestrings. + """ + if isinstance(cmdstring, unicode): + cmdstring = cmdstring.encode('utf-8', errors='ignore') + return shlex.split(cmdstring) + def safely_get(clb, E, on_error=''): """ returns result of :func:`clb` and falls back to `on_error` |