[PATCH] Fix win32 command processor quoting in system() calls

Benoit Boissinot bboissin at gmail.com
Fri Dec 15 20:44:46 UTC 2006


On 12/15/06, Patrick Mezard <pmezard at gmail.com> wrote:
> # HG changeset patch
> # User Patrick Mezard <pmezard at gmail.com>
> # Date 1166167774 -3600
> # Node ID 0f2f187d1c69e6e2507abf1238f2f12d7f8d99ff
> # Parent  c0a12e6441a5abb669fcd62cc9719220c255fcd5
> Fix win32 command processor quoting in system() calls.
>
> Win32 command processor does strange things regarding quotes. Sometimes, it
> just strips the leading and ending command quotes. Try to anticipate this
> behaviour documented in CMD.EXE man page, and add quotes preventively.
>
> diff -r c0a12e6441a5 -r 0f2f187d1c69 mercurial/util.py
> --- a/mercurial/util.py Tue Dec 12 17:52:33 2006 -0600
> +++ b/mercurial/util.py Fri Dec 15 08:29:34 2006 +0100
> @@ -506,7 +506,7 @@ def system(cmd, environ={}, cwd=None, on
>              os.environ[k] = py2shell(v)
>          if cwd is not None and oldcwd != cwd:
>              os.chdir(cwd)
> -        rc = os.system(cmd)
> +        rc = os_system(cmd)
>          if rc and onerr:
>              errmsg = '%s %s' % (os.path.basename(cmd.split(None, 1)[0]),
>                                  explain_exit(rc)[0])
> @@ -904,6 +904,9 @@ else:
>          if st is None:
>              st = fstat(fp)
>          return st.st_uid == os.getuid()
> +
> +    def os_system(cmd):
> +        return os.system(cmd)

os_system = os.system

>
>  def _buildencodefun():
>      e = '_'
> diff -r c0a12e6441a5 -r 0f2f187d1c69 mercurial/util_win32.py
> --- a/mercurial/util_win32.py   Tue Dec 12 17:52:33 2006 -0600
> +++ b/mercurial/util_win32.py   Fri Dec 15 08:29:34 2006 +0100
> @@ -197,6 +197,48 @@ def user_rcpath():
>              shell.SHGetSpecialFolderLocation(0, shellcon.CSIDL_APPDATA))
>          userdir = os.path.dirname(appdir)
>      return os.path.join(userdir, 'mercurial.ini')
> +
> +
> +cmd_special_chars = '&<>()@^|'
> +
> +def preserve_quotes(cmd):
> +    '''Test if quotes in cmd are preserved or not by the command processor (see
> +    cmd.exe man page for details.
> +    '''
> +    #Exactly two quotes characters
> +    if cmd.count('"')!=2:
> +        return False
> +    # String within quotes must have at least one whitespace character and no
> +    # special ones.
> +    quote1 = cmd.find('"')
> +    quote2 = cmd[quote1+1:].find('"')
> +    quoted = cmd[quote1+1:quote2]
> +    whitespaces = 0
> +    for c in quoted:
> +        if c in cmd_special_chars:
> +            return False
> +        if c == ' ':
> +            whitespaces += 1
> +    if whitespaces==0:
> +        return False
> +    # String within quotes must be the name of an executable file
> +    if not os.path.isfile(quoted):
> +        return False
> +    pathext = os.environ.get('PATHEXT', '').lower().split(';')

what is this part about ? (maybe you want to use find_in_path ?)

regards,

Benoit



More information about the Mercurial-devel mailing list