https://git.reactos.org/?p=reactos.git;a=commitdiff;h=0c6498fa67f32d83ccf5505f2dc9ac6e5c1c2541
commit 0c6498fa67f32d83ccf5505f2dc9ac6e5c1c2541 Author: Amine Khaldi <amine.kha...@reactos.org> AuthorDate: Sun Oct 8 09:33:23 2017 +0100 [MSIEXEC] Sync with Wine Staging 2.16. CORE-13762 d73c38f msiexec: Fix parsing of command lines where quoted strings and properties are not separated by whitespace. --- base/system/msiexec/msiexec.c | 169 ++++++++++++++++++++++-------------------- media/doc/README.WINE | 2 +- 2 files changed, 88 insertions(+), 83 deletions(-) diff --git a/base/system/msiexec/msiexec.c b/base/system/msiexec/msiexec.c index 44f1f28862..f2155622de 100644 --- a/base/system/msiexec/msiexec.c +++ b/base/system/msiexec/msiexec.c @@ -212,14 +212,6 @@ static DWORD msi_atou(LPCWSTR str) return ret; } -static LPWSTR msi_strdup(LPCWSTR str) -{ - DWORD len = lstrlenW(str)+1; - LPWSTR ret = HeapAlloc(GetProcessHeap(), 0, sizeof(WCHAR)*len); - lstrcpyW(ret, str); - return ret; -} - /* str1 is the same as str2, ignoring case */ static BOOL msi_strequal(LPCWSTR str1, LPCSTR str2) { @@ -409,90 +401,103 @@ static INT DoEmbedding( LPWSTR key ) enum chomp_state { - cs_whitespace, - cs_token, - cs_quote + CS_WHITESPACE, + CS_TOKEN, + CS_QUOTE }; -static int chomp( WCHAR *str ) +static int chomp( const WCHAR *in, WCHAR *out ) { - enum chomp_state state = cs_token; - WCHAR *p, *out; - int count = 1; - BOOL ignore; - - for( p = str, out = str; *p; p++ ) - { - ignore = TRUE; - switch( state ) - { - case cs_whitespace: - switch( *p ) - { - case ' ': - break; - case '"': - state = cs_quote; - count++; - break; - default: - count++; - ignore = FALSE; - state = cs_token; - } - break; - - case cs_token: - switch( *p ) - { - case '"': - state = cs_quote; - break; - case ' ': - state = cs_whitespace; - *out++ = 0; - break; - default: - ignore = FALSE; - } - break; - - case cs_quote: - switch( *p ) - { - case '"': - state = cs_token; - break; - default: - ignore = FALSE; - } - break; - } - if( !ignore ) - *out++ = *p; - } - - *out = 0; + enum chomp_state state = CS_TOKEN; + const WCHAR *p; + int count = 1; + BOOL ignore; - return count; + for (p = in; *p; p++) + { + ignore = TRUE; + switch (state) + { + case CS_WHITESPACE: + switch (*p) + { + case ' ': + break; + case '"': + state = CS_QUOTE; + count++; + break; + default: + count++; + ignore = FALSE; + state = CS_TOKEN; + } + break; + + case CS_TOKEN: + switch (*p) + { + case '"': + state = CS_QUOTE; + break; + case ' ': + state = CS_WHITESPACE; + if (out) *out++ = 0; + break; + default: + if (p > in && p[-1] == '"') + { + if (out) *out++ = 0; + count++; + } + ignore = FALSE; + } + break; + + case CS_QUOTE: + switch (*p) + { + case '"': + state = CS_TOKEN; + break; + default: + ignore = FALSE; + } + break; + } + if (!ignore && out) *out++ = *p; + } + if (out) *out = 0; + return count; } static void process_args( WCHAR *cmdline, int *pargc, WCHAR ***pargv ) { - WCHAR **argv, *p = msi_strdup(cmdline); - int i, n; + WCHAR **argv, *p; + int i, count; - n = chomp( p ); - argv = HeapAlloc(GetProcessHeap(), 0, sizeof (WCHAR*)*(n+1)); - for( i=0; i<n; i++ ) - { - argv[i] = p; - p += lstrlenW(p) + 1; - } - argv[i] = NULL; + *pargc = 0; + *pargv = NULL; + + count = chomp( cmdline, NULL ); + if (!(p = HeapAlloc( GetProcessHeap(), 0, (lstrlenW(cmdline) + count + 1) * sizeof(WCHAR) ))) + return; + + count = chomp( cmdline, p ); + if (!(argv = HeapAlloc( GetProcessHeap(), 0, (count + 1) * sizeof(WCHAR *) ))) + { + HeapFree( GetProcessHeap(), 0, p ); + return; + } + for (i = 0; i < count; i++) + { + argv[i] = p; + p += lstrlenW( p ) + 1; + } + argv[i] = NULL; - *pargc = n; - *pargv = argv; + *pargc = count; + *pargv = argv; } static BOOL process_args_from_reg( const WCHAR *ident, int *pargc, WCHAR ***pargv ) diff --git a/media/doc/README.WINE b/media/doc/README.WINE index 778f42f7b4..1eca9ef9cc 100644 --- a/media/doc/README.WINE +++ b/media/doc/README.WINE @@ -243,7 +243,7 @@ reactos/base/applications/wordpad # Synced to WineStaging-1.9.16 reactos/base/applications/write # Synced to WineStaging-2.9 reactos/base/services/rpcss # Synced to WineStaging-1.9.16 reactos/base/system/expand # Synced to WineStaging-2.9 -reactos/base/system/msiexec # Synced to WineStaging-2.9 +reactos/base/system/msiexec # Synced to WineStaging-2.16 reactos/modules/rosapps/winfile # Autosync In addition the following libs, dlls and source files are mostly based on code ported