From bb9db9720486339ec788b49a539f432e6671dc79 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Marc-Andr=C3=A9=20Moreau?= Date: Sat, 21 Sep 2013 20:05:14 -0400 Subject: [PATCH] libwinpr-thread: improve CommandLineToArgv completeness --- winpr/libwinpr/thread/argv.c | 69 +++++++++++++--------- winpr/libwinpr/thread/test/CMakeLists.txt | 2 +- .../thread/test/TestThreadCommandLineToArgv.c | 16 +++++ 3 files changed, 57 insertions(+), 30 deletions(-) diff --git a/winpr/libwinpr/thread/argv.c b/winpr/libwinpr/thread/argv.c index 01c887a..1369742 100644 --- a/winpr/libwinpr/thread/argv.c +++ b/winpr/libwinpr/thread/argv.c @@ -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; diff --git a/winpr/libwinpr/thread/test/CMakeLists.txt b/winpr/libwinpr/thread/test/CMakeLists.txt index 8d03a25..f05e033 100644 --- a/winpr/libwinpr/thread/test/CMakeLists.txt +++ b/winpr/libwinpr/thread/test/CMakeLists.txt @@ -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}) diff --git a/winpr/libwinpr/thread/test/TestThreadCommandLineToArgv.c b/winpr/libwinpr/thread/test/TestThreadCommandLineToArgv.c index 2e17765..e4573d9 100644 --- a/winpr/libwinpr/thread/test/TestThreadCommandLineToArgv.c +++ b/winpr/libwinpr/thread/test/TestThreadCommandLineToArgv.c @@ -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; } -- 2.7.4