[PATCH] programs/explorer: Fix explorer's command line parsing

Jay Yang jkelleyy at gmail.com
Wed Jan 4 15:49:41 CST 2012


The previous method for parsing simply searched for the '/' character so it would accidentally eat
parts of URLs if they contained '/'. This should fix bug #28029. I've also changed it so command
line flags are case insensitive (as it is on windows).

---
 programs/explorer/explorer.c |   91 ++++++++++++++++++++---------------------
 1 files changed, 44 insertions(+), 47 deletions(-)

diff --git a/programs/explorer/explorer.c b/programs/explorer/explorer.c
index 35080a3..e36c70f 100644
--- a/programs/explorer/explorer.c
+++ b/programs/explorer/explorer.c
@@ -683,56 +683,53 @@ static void copy_path_root(LPWSTR root, LPWSTR path)
  */
 static void parse_command_line(LPWSTR commandline,parameters_struct *parameters)
 {
-    static const WCHAR arg_n[] = {'/','n'};
-    static const WCHAR arg_e[] = {'/','e',','};
-    static const WCHAR arg_root[] = {'/','r','o','o','t',','};
-    static const WCHAR arg_select[] = {'/','s','e','l','e','c','t',','};
-    static const WCHAR arg_desktop[] = {'/','d','e','s','k','t','o','p'};
+    static const WCHAR arg_n[] = {'/','n','\0'};
+    static const WCHAR arg_e[] = {'/','e',',','\0'};
+    static const WCHAR arg_root[] = {'/','r','o','o','t','\0'};
+    static const WCHAR arg_select[] = {'/','s','e','l','e','c','t','\0'};
+    static const WCHAR arg_desktop[] = {'/','d','e','s','k','t','o','p','\0'};
 -    LPWSTR p, p2;
-
-    p2 = commandline;
-    p = strchrW(commandline,'/');
-    while(p)
-    {
-        if (strncmpW(p, arg_n, sizeof(arg_n)/sizeof(WCHAR))==0)
-        {
-            parameters->explorer_mode = FALSE;
-            p += sizeof(arg_n)/sizeof(WCHAR);
-        }
-        else if (strncmpW(p, arg_e, sizeof(arg_e)/sizeof(WCHAR))==0)
-        {
-            parameters->explorer_mode = TRUE;
-            p += sizeof(arg_e)/sizeof(WCHAR);
-        }
-        else if (strncmpW(p, arg_root, sizeof(arg_root)/sizeof(WCHAR))==0)
-        {
-            p += sizeof(arg_root)/sizeof(WCHAR);
-            p+=copy_path_string(parameters->root,p);
-        }
-        else if (strncmpW(p, arg_select, sizeof(arg_select)/sizeof(WCHAR))==0)
-        {
-            p += sizeof(arg_select)/sizeof(WCHAR);
-            p+=copy_path_string(parameters->selection,p);
-            if (!parameters->root[0])
-                copy_path_root(parameters->root,
-                               parameters->selection);
-        }
-        else if (strncmpW(p, arg_desktop, sizeof(arg_desktop)/sizeof(WCHAR))==0)
-        {
-            p += sizeof(arg_desktop)/sizeof(WCHAR);
-            manage_desktop( p );  /* the rest of the command line is handled by desktop mode */
+    int argc;
+    int i;
+    LPWSTR *argv;
+    if(commandline[0]=='\0')
+        return;
+    argv = CommandLineToArgvW(commandline,&argc);
+    for(i=0;i<argc;i++){
+        LPWSTR curr=argv[i];
+        if(*curr!='/')
+            copy_path_string(parameters->root,curr);
+        while(*curr=='/'){
+            LPWSTR end=strchrW(curr,',');
+            LPWSTR next;
+            if(end==NULL)
+                next=(end=strchrW(curr,'\0'));
+            else
+                next=end+1;
+            *end='\0';
+            if (strcmpiW(curr, arg_n)==0)
+                parameters->explorer_mode = FALSE;
+            else if (strcmpiW(curr, arg_e)==0)
+                parameters->explorer_mode = TRUE;
+            else if (strcmpiW(curr, arg_root)==0)
+                next+=copy_path_string(parameters->root,next);
+            else if (strcmpiW(curr, arg_select)==0)
+            {
+                next+=copy_path_string(parameters->selection,next);
+                if (!parameters->root[0])
+                    copy_path_root(parameters->root,parameters->selection);
+            }
+            else if (strcmpiW(curr, arg_desktop)==0)
+            {
+                /* we free argv here since manage_desktop doesn't return */
+                LocalFree(argv);
+                /* the rest of the command line is handled by desktop mode */
+                manage_desktop(StrStrIW(commandline,arg_desktop)+lstrlenW(arg_desktop));
+            }
+            curr=next;
         }
-        else p++;
-
-        p2 = p;
-        p = strchrW(p,'/');
-    }
-    if (p2 && *p2)
-    {
-        /* left over command line is generally the path to be opened */
-        copy_path_string(parameters->root,p2);
     }
+    LocalFree(argv);
 }
  int WINAPI wWinMain(HINSTANCE hinstance,
-- 
1.7.7




More information about the wine-patches mailing list