Changeset 977


Ignore:
Timestamp:
5/5/2009 1:08:20 PM (6 years ago)
Author:
lowjoel
Message:

Added escaping and unescaping code for command line generation/parsing to enable pathnames containing = and ,. Fixes #207.

Location:
branches/eraser6
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • branches/eraser6/Eraser/Program.cs

    r952 r977  
    696696                while (commaPos != -1) 
    697697                { 
    698                     //Extract the current subparameter, and dissect the subparameter at 
    699                     //the first =. 
    700                     string subParam = param.Substring(lastPos, commaPos - lastPos); 
    701                     int equalPos = subParam.IndexOf('='); 
    702                     if (equalPos == -1) 
    703                         result.Add(new KeyValuePair<string, string>(subParam, null)); 
     698                    //Check that the first parameter is not a \ otherwise this comma 
     699                    //is escaped 
     700                    if (commaPos == 0 ||                                    //No possibility of escaping 
     701                        (commaPos >= 1 && param[commaPos - 1] != '\\') ||   //Second character 
     702                        (commaPos >= 2 && param[commaPos - 2] == '\\'))     //Cannot be a \\ which is an escape 
     703                    { 
     704                        //Extract the current subparameter, and dissect the subparameter 
     705                        //at the first =. 
     706                        string subParam = param.Substring(lastPos, commaPos - lastPos); 
     707                        int equalPos = -1; 
     708 
     709                        do 
     710                        { 
     711                            equalPos = subParam.IndexOf('=', equalPos + 1); 
     712                            if (equalPos == -1) 
     713                            { 
     714                                result.Add(new KeyValuePair<string, string>( 
     715                                    UnescapeCommandLine(subParam), null)); 
     716                            } 
     717                            else if (equalPos == 0 ||                               //No possibility of escaping 
     718                                (equalPos >= 1 && subParam[equalPos - 1] != '\\') ||//Second character 
     719                                (equalPos >= 2 && subParam[equalPos - 2] == '\\'))  //Double \\ which is an escape 
     720                            { 
     721                                result.Add(new KeyValuePair<string, string>( 
     722                                    UnescapeCommandLine(subParam.Substring(0, equalPos)), 
     723                                    UnescapeCommandLine(subParam.Substring(equalPos + 1)))); 
     724                                break; 
     725                            } 
     726                        } 
     727                        while (equalPos != -1); 
     728                        lastPos = ++commaPos; 
     729                    } 
    704730                    else 
    705                         result.Add(new KeyValuePair<string, string>(subParam.Substring(0, equalPos), 
    706                             subParam.Substring(equalPos + 1))); 
     731                        ++commaPos; 
    707732 
    708733                    //Find the next , 
    709                     lastPos = ++commaPos; 
    710734                    commaPos = param.IndexOf(',', commaPos); 
    711735                } 
    712736 
    713737                return result; 
     738            } 
     739 
     740            /// <summary> 
     741            /// Unescapes a subparameter command line, removing the extra  
     742            /// </summary> 
     743            /// <param name="param"></param> 
     744            /// <returns></returns> 
     745            private static string UnescapeCommandLine(string param) 
     746            { 
     747                StringBuilder result = new StringBuilder(param.Length); 
     748                for (int i = 0; i < param.Length; ++i) 
     749                    if (param[i] == '\\' && i < param.Length - 1) 
     750                        result.Append(param[++i]); 
     751                    else 
     752                        result.Append(param[i]); 
     753                return result.ToString(); 
    714754            } 
    715755 
     
    11051145            try 
    11061146            { 
    1107                 using (Program.eraserClient = new RemoteExecutorClient()) 
    1108                 { 
    1109                     if (!((RemoteExecutorClient)Program.eraserClient).Connect()) 
     1147                using (RemoteExecutorClient client = new RemoteExecutorClient()) 
     1148                { 
     1149                    client.Run(); 
     1150                    if (!client.IsConnected) 
    11101151                    { 
    11111152                        //The client cannot connect to the server. This probably means 
     
    11151156                        eraserInstance.WaitForInputIdle(); 
    11161157 
    1117                         if (!((RemoteExecutorClient)Program.eraserClient).Connect()) 
     1158                        client.Run(); 
     1159                        if (!client.IsConnected) 
    11181160                            throw new IOException("Eraser cannot connect to the running " + 
    11191161                                "instance for erasures."); 
    11201162                    } 
    11211163 
    1122                     Program.eraserClient.Run(); 
    1123                     Program.eraserClient.Tasks.Add(task); 
     1164                    client.Tasks.Add(task); 
    11241165                } 
    11251166            } 
  • branches/eraser6/ShellExt/CtxMenu.cpp

    r878 r977  
    533533                        DWORD attributes = GetFileAttributes(item.c_str()); 
    534534 
     535                        //Escape the command line (= and , are special characters) 
     536                        std::wstring escapedItem; 
     537                        escapedItem.reserve(item.length()); 
     538                        for (std::wstring::const_iterator i = item.begin(); i != item.end(); ++i) 
     539                        { 
     540                            if (wcschr(L"\\=,", *i)) 
     541                                escapedItem += '\\'; 
     542                            escapedItem += *i; 
     543                        } 
     544 
    535545                        //Add the correct command line for the file type. 
    536546                        if (attributes & FILE_ATTRIBUTE_DIRECTORY) 
    537                             commandLine += L"\"-d=" + item + L"\" "; 
     547                            commandLine += L"\"-d=" + escapedItem + L"\" "; 
    538548                        else 
    539                             commandLine += L"\"" + item + L"\" "; 
     549                            commandLine += L"\"" + escapedItem + L"\" "; 
    540550                    } 
    541551                } 
     
    740750            finalParameters = parametersStrm.str(); 
    741751        } 
     752        MessageBox(NULL, finalParameters.c_str(), L"Eraser Command Line", MB_OK | MB_ICONINFORMATION); 
    742753 
    743754        //If the process must be elevated we use ShellExecute with the runas verb 
Note: See TracChangeset for help on using the changeset viewer.