libwinpr-thread: improve CommandLineToArgv completeness
authorMarc-André Moreau <marcandre.moreau@gmail.com>
Sun, 22 Sep 2013 00:05:14 +0000 (20:05 -0400)
committerMarc-André Moreau <marcandre.moreau@gmail.com>
Sun, 22 Sep 2013 00:05:14 +0000 (20:05 -0400)
winpr/libwinpr/thread/argv.c
winpr/libwinpr/thread/test/CMakeLists.txt
winpr/libwinpr/thread/test/TestThreadCommandLineToArgv.c

index 01c887a..1369742 100644 (file)
@@ -122,59 +122,70 @@ LPSTR* CommandLineToArgvA(LPCSTR lpCmdLine, int* pNumArgs)
        if (strstr(lpCmdLine, "\\\""))
        {
                int i, n;
+               char* pLastEnd = NULL;
 
                lpEscapedCmdLine = (char*) malloc(cmdLineLength + 1);
 
                p = (char*) lpCmdLine;
+               pLastEnd = (char*) lpCmdLine;
                pOutput = (char*) lpEscapedCmdLine;
 
-               pBeg = strstr(lpCmdLine, "\\\"");
-               pEnd = pBeg + 2;
-
-               while (pBeg >= lpCmdLine)
+               while (p < &lpCmdLine[cmdLineLength])
                {
-                       if (*pBeg != '\\')
+                       pBeg = strstr(p, "\\\"");
+
+                       if (!pBeg)
                        {
-                               pBeg++;
+                               length = strlen(p);
+                               CopyMemory(pOutput, p, length);
+                               pOutput += length;
+                               p += length;
+
                                break;
                        }
 
-                       pBeg--;
-               }
+                       pEnd = pBeg + 2;
 
-               n = (pEnd - pBeg) - 1;
+                       while (pBeg >= lpCmdLine)
+                       {
+                               if (*pBeg != '\\')
+                               {
+                                       pBeg++;
+                                       break;
+                               }
 
-               length = (pBeg - lpCmdLine);
-               CopyMemory(pOutput, p, length);
-               pOutput += length;
-               p += length;
+                               pBeg--;
+                       }
 
-               for (i = 0; i < (n / 2); i++)
-               {
-                       *pOutput = '\\';
-                       pOutput++;
-               }
+                       n = (pEnd - pBeg) - 1;
 
-               p += n + 1;
+                       length = (pBeg - pLastEnd);
+                       CopyMemory(pOutput, p, length);
+                       pOutput += length;
+                       p += length;
 
-               if ((n % 2) != 0)
-                       lpEscapedChars[pOutput - lpEscapedCmdLine] = '\\';
+                       for (i = 0; i < (n / 2); i++)
+                       {
+                               *pOutput = '\\';
+                               pOutput++;
+                       }
 
-               *pOutput = '"';
-               pOutput++;
+                       p += n + 1;
 
-               length = cmdLineLength - (pEnd - lpCmdLine);
-               CopyMemory(pOutput, p, length);
-               pOutput += length;
-               p += length;
+                       if ((n % 2) != 0)
+                               lpEscapedChars[pOutput - lpEscapedCmdLine] = '\\';
+
+                       *pOutput = '"';
+                       pOutput++;
+
+                       pLastEnd = p;
+               }
 
                *pOutput = '\0';
                pOutput++;
 
                lpCmdLine = (LPCSTR) lpEscapedCmdLine;
                cmdLineLength = strlen(lpCmdLine);
-
-               //printf("EscapedCmdLine: %s\n", lpEscapedCmdLine);
        }
 
        maxNumArgs = 1;
index 8d03a25..f05e033 100644 (file)
@@ -16,7 +16,7 @@ add_executable(${MODULE_NAME} ${${MODULE_PREFIX}_SRCS})
 set_complex_link_libraries(VARIABLE ${MODULE_PREFIX}_LIBS
        MONOLITHIC ${MONOLITHIC_BUILD}
        MODULE winpr
-       MODULES winpr-thread)
+       MODULES winpr-thread winpr-heap)
 
 target_link_libraries(${MODULE_NAME} ${${MODULE_PREFIX}_LIBS})
 
index 2e17765..e4573d9 100644 (file)
@@ -62,6 +62,19 @@ const char* test_args_list_6[] =
        NULL
 };
 
+const char* test_args_line_7 = "a\\\\\\\\\"b c\" d e f\\\\\\\\\"g h\" i j";
+
+const char* test_args_list_7[] =
+{
+       "a\\\\b c",
+       "d",
+       "e",
+       "f\\\\g h",
+       "i",
+       "j",
+       NULL
+};
+
 static int test_command_line_parsing_case(const char* line, const char** list)
 {
        int i;
@@ -82,6 +95,8 @@ static int test_command_line_parsing_case(const char* line, const char** list)
                printf("argv[%d] = %s\n", i, pArgs[i]);
        }
 
+       HeapFree(GetProcessHeap(), 0, pArgs);
+
        return 0;
 }
 
@@ -93,6 +108,7 @@ int TestThreadCommandLineToArgv(int argc, char* argv[])
        test_command_line_parsing_case(test_args_line_4, test_args_list_4);
        test_command_line_parsing_case(test_args_line_5, test_args_list_5);
        test_command_line_parsing_case(test_args_line_6, test_args_list_6);
+       test_command_line_parsing_case(test_args_line_7, test_args_list_7);
 
        return 0;
 }