Commit b1f04e23 authored by Daniel Lehman's avatar Daniel Lehman Committed by Alexandre Julliard

kernel32: If string arg to FormatMessage is NULL, use "(null)" instead of crashing.

parent 4e7b3bad
...@@ -135,15 +135,18 @@ static LPCWSTR format_insert( BOOL unicode_caller, int insert, LPCWSTR format, ...@@ -135,15 +135,18 @@ static LPCWSTR format_insert( BOOL unicode_caller, int insert, LPCWSTR format,
if (*format != '!') /* simple string */ if (*format != '!') /* simple string */
{ {
arg = get_arg( insert, flags, args ); arg = get_arg( insert, flags, args );
if (unicode_caller) if (unicode_caller || !arg)
{ {
WCHAR *str = (WCHAR *)arg; static const WCHAR nullW[] = {'(','n','u','l','l',')',0};
const WCHAR *str = (const WCHAR *)arg;
if (!str) str = nullW;
*result = HeapAlloc( GetProcessHeap(), 0, (strlenW(str) + 1) * sizeof(WCHAR) ); *result = HeapAlloc( GetProcessHeap(), 0, (strlenW(str) + 1) * sizeof(WCHAR) );
strcpyW( *result, str ); strcpyW( *result, str );
} }
else else
{ {
char *str = (char *)arg; const char *str = (const char *)arg;
DWORD length = MultiByteToWideChar( CP_ACP, 0, str, -1, NULL, 0 ); DWORD length = MultiByteToWideChar( CP_ACP, 0, str, -1, NULL, 0 );
*result = HeapAlloc( GetProcessHeap(), 0, length * sizeof(WCHAR) ); *result = HeapAlloc( GetProcessHeap(), 0, length * sizeof(WCHAR) );
MultiByteToWideChar( CP_ACP, 0, str, -1, *result, length ); MultiByteToWideChar( CP_ACP, 0, str, -1, *result, length );
......
...@@ -125,6 +125,7 @@ static void test_message_from_string_wide(void) ...@@ -125,6 +125,7 @@ static void test_message_from_string_wide(void)
static const WCHAR s_sp002sp001[] = {' ',' ','0','0','0','2',',',' ',' ','0','0','1',0}; static const WCHAR s_sp002sp001[] = {' ',' ','0','0','0','2',',',' ',' ','0','0','1',0};
static const WCHAR s_sp002sp003[] = {' ',' ','0','0','0','2',',',' ','0','0','0','0','3',0}; static const WCHAR s_sp002sp003[] = {' ',' ','0','0','0','2',',',' ','0','0','0','0','3',0};
static const WCHAR s_sp001004[] = {' ',' ','0','0','1',',','0','0','0','0','0','4',0}; static const WCHAR s_sp001004[] = {' ',' ','0','0','1',',','0','0','0','0','0','4',0};
static const WCHAR s_null[] = {'(','n','u','l','l',')',0};
static const WCHAR init_buf[] = {'x', 'x', 'x', 'x', 'x', 'x'}; static const WCHAR init_buf[] = {'x', 'x', 'x', 'x', 'x', 'x'};
static const WCHAR broken_buf[] = {'t','e','s','t','x','x'}; static const WCHAR broken_buf[] = {'t','e','s','t','x','x'};
...@@ -381,6 +382,12 @@ static void test_message_from_string_wide(void) ...@@ -381,6 +382,12 @@ static void test_message_from_string_wide(void)
ok(!lstrcmpW(s_crlfcrlf, out), "failed out=%s\n", wine_dbgstr_w(out)); ok(!lstrcmpW(s_crlfcrlf, out), "failed out=%s\n", wine_dbgstr_w(out));
ok(r==4,"failed: r=%d\n", r); ok(r==4,"failed: r=%d\n", r);
/* null string as argument */
r = doitW(FORMAT_MESSAGE_FROM_STRING, fmt_1, 0,
0, out, sizeof(out)/sizeof(WCHAR), NULL);
ok(!lstrcmpW(s_null, out),"failed out=[%s]\n", wine_dbgstr_w(out));
ok(r==6,"failed: r=%d\n",r);
/* precision and width */ /* precision and width */
r = doitW(FORMAT_MESSAGE_FROM_STRING, fmt_13s, r = doitW(FORMAT_MESSAGE_FROM_STRING, fmt_13s,
...@@ -700,6 +707,12 @@ static void test_message_from_string(void) ...@@ -700,6 +707,12 @@ static void test_message_from_string(void)
ok(!strcmp("\r\n\r\n", out),"failed out=[%s]\n",out); ok(!strcmp("\r\n\r\n", out),"failed out=[%s]\n",out);
ok(r==4,"failed: r=%d\n",r); ok(r==4,"failed: r=%d\n",r);
/* null string as argument */
r = doit(FORMAT_MESSAGE_FROM_STRING, "%1", 0,
0, out, sizeof(out)/sizeof(CHAR), NULL);
ok(!strcmp("(null)", out),"failed out=[%s]\n",out);
ok(r==6,"failed: r=%d\n",r);
/* precision and width */ /* precision and width */
r = doit(FORMAT_MESSAGE_FROM_STRING, "%1!3s!", r = doit(FORMAT_MESSAGE_FROM_STRING, "%1!3s!",
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment