From 2c6ca6f1fae9f3101b11a15e78fd632d70035bbb Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Fri, 18 Jul 2008 22:22:16 +0000 Subject: [PATCH] mention compatibility implications of wxExecute() quoting changes; don't change quoting of already quoted arguments in 2.8 for compatibility; also fix handling of empty arguments as a side effect (see #4115) git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/branches/WX_2_8_BRANCH@54695 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- docs/changes.txt | 6 ++++++ src/msw/utilsexc.cpp | 41 +++++++++++++++++++++++++++++++++-------- 2 files changed, 39 insertions(+), 8 deletions(-) diff --git a/docs/changes.txt b/docs/changes.txt index 195569b43c..bf8a704222 100644 --- a/docs/changes.txt +++ b/docs/changes.txt @@ -117,6 +117,12 @@ All (Unix): wxMSW: ++ Potentially incompatible change: wxExecute() arguments are now quoted if they + contain spaces and existing quotes are escaped with a backslash. However, to + preserve compatibility, the argument is unchanged if it is already quoted. + Notice that this behaviour will change in wxWidgets 3.0 where all arguments + will be quoted, please update your code now if you are affected and use only + wxWidgets 2.8.9 or later. - Fix keyboard support in wxSpinCtrl broken in 2.8.8. - Compile fix for WinCE in window.cpp (no VkKeyScan in Windows CE). - Fix quoting of arguments passed to wxExecute(char **) (Brian Ravnsgaard Riis). diff --git a/src/msw/utilsexc.cpp b/src/msw/utilsexc.cpp index 1237c4d429..d41d3382d0 100644 --- a/src/msw/utilsexc.cpp +++ b/src/msw/utilsexc.cpp @@ -957,16 +957,41 @@ long wxExecute(wxChar **argv, int flags, wxProcess *handler) { arg = *argv++; - // escape any quotes present in the string to avoid interfering with - // the command line parsing in the child process - arg.Replace(_T("\""), _T("\\\""), true /* replace all */); + // we didn't quote the arguments properly in the previous wx versions + // and while this is the right thing to do, there is a good chance that + // people worked around our bug in their code by quoting the arguments + // manually before, so, for compatibility sake, keep the argument + // unchanged if it's already quoted - // and quote any arguments containing the spaces to prevent them from - // being broken down - if ( arg.find_first_of(_T(" \t")) == wxString::npos ) - command += arg; - else + bool quote; + if ( arg.empty() ) + { + // we need to quote empty arguments, otherwise they'd just + // disappear + quote = true; + } + else // non-empty + { + if ( *arg.begin() != _T('"') || *arg.rbegin() != _T('"') ) + { + // escape any quotes present in the string to avoid interfering + // with the command line parsing in the child process + arg.Replace(_T("\""), _T("\\\""), true /* replace all */); + + // and quote any arguments containing the spaces to prevent + // them from being broken down + quote = arg.find_first_of(_T(" \t")) != wxString::npos; + } + else // already quoted + { + quote = false; + } + } + + if ( quote ) command += _T('\"') + arg + _T('\"'); + else + command += arg; if ( !*argv ) break;