kernel32: Reject a format string with insertions if no variadic arguments are passed to FormatMessageA/W.

This commit is contained in:
Andrew Nguyen 2010-05-01 03:40:46 -05:00 committed by Alexandre Julliard
parent c22d776e74
commit f2c91f0d3c
2 changed files with 71 additions and 0 deletions

View File

@ -296,6 +296,13 @@ static LPWSTR format_message( BOOL unicode_caller, DWORD dwFlags, LPCWSTR fmtstr
case '6':case '7':case '8':case '9': case '6':case '7':case '8':case '9':
if (dwFlags & FORMAT_MESSAGE_IGNORE_INSERTS) if (dwFlags & FORMAT_MESSAGE_IGNORE_INSERTS)
goto ignore_inserts; goto ignore_inserts;
else if (((dwFlags & FORMAT_MESSAGE_ARGUMENT_ARRAY) && !format_args->args) ||
(!(dwFlags & FORMAT_MESSAGE_ARGUMENT_ARRAY) && !format_args->list))
{
SetLastError(ERROR_INVALID_PARAMETER);
HeapFree(GetProcessHeap(), 0, target);
return NULL;
}
insertnr = *f-'0'; insertnr = *f-'0';
switch (f[1]) { switch (f[1]) {
case '0':case '1':case '2':case '3': case '0':case '1':case '2':case '3':

View File

@ -180,6 +180,27 @@ static void test_message_from_string_wide(void)
ok(r==0, "succeeded: r=%d\n", r); ok(r==0, "succeeded: r=%d\n", r);
ok(error==ERROR_INVALID_PARAMETER, "last error %u\n", error); ok(error==ERROR_INVALID_PARAMETER, "last error %u\n", error);
/* insertion with no variadic arguments */
SetLastError(0xdeadbeef);
memcpy(out, init_buf, sizeof(init_buf));
r = FormatMessageW(FORMAT_MESSAGE_FROM_STRING, fmt_1, 0,
0, out, sizeof(out)/sizeof(WCHAR), NULL);
error = GetLastError();
ok(!memcmp(out, init_buf, sizeof(init_buf)),
"Expected the buffer to be unchanged\n");
ok(r==0, "succeeded: r=%d\n", r);
ok(error==ERROR_INVALID_PARAMETER, "last error %u\n", error);
SetLastError(0xdeadbeef);
memcpy(out, init_buf, sizeof(init_buf));
r = FormatMessageW(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_ARGUMENT_ARRAY, fmt_1, 0,
0, out, sizeof(out)/sizeof(WCHAR), NULL);
error = GetLastError();
ok(!memcmp(out, init_buf, sizeof(init_buf)),
"Expected the buffer to be unchanged\n");
ok(r==0, "succeeded: r=%d\n", r);
ok(error==ERROR_INVALID_PARAMETER, "last error %u\n", error);
/* using the format feature */ /* using the format feature */
r = doitW(FORMAT_MESSAGE_FROM_STRING, fmt_1s, 0, r = doitW(FORMAT_MESSAGE_FROM_STRING, fmt_1s, 0,
0, out, sizeof(out)/sizeof(WCHAR), test); 0, out, sizeof(out)/sizeof(WCHAR), test);
@ -483,6 +504,35 @@ static void test_message_from_string(void)
ok(GetLastError()==ERROR_INVALID_PARAMETER, ok(GetLastError()==ERROR_INVALID_PARAMETER,
"last error %u\n", GetLastError()); "last error %u\n", GetLastError());
/* insertion with no variadic arguments */
SetLastError(0xdeadbeef);
memcpy(out, init_buf, sizeof(init_buf));
r = FormatMessageA(FORMAT_MESSAGE_FROM_STRING, "%1", 0,
0, out, sizeof(out)/sizeof(CHAR), NULL);
ok(!memcmp(out, init_buf, sizeof(init_buf)) ||
broken(!strcmp("%1", out)), /* Win9x */
"Expected the buffer to be untouched\n");
ok(r==0 ||
broken(r==2), /* Win9x */
"succeeded: r=%d\n", r);
ok(GetLastError()==ERROR_INVALID_PARAMETER ||
broken(GetLastError()==0xdeadbeef), /* Win9x */
"last error %u\n", GetLastError());
SetLastError(0xdeadbeef);
memcpy(out, init_buf, sizeof(init_buf));
r = FormatMessageA(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_ARGUMENT_ARRAY, "%1", 0,
0, out, sizeof(out)/sizeof(CHAR), NULL);
ok(!memcmp(out, init_buf, sizeof(init_buf)) ||
broken(!strcmp("%1", out)), /* Win9x */
"Expected the buffer to be untouched\n");
ok(r==0 ||
broken(r==2), /* Win9x */
"succeeded: r=%d\n", r);
ok(GetLastError()==ERROR_INVALID_PARAMETER ||
broken(GetLastError()==0xdeadbeef), /* Win9x */
"last error %u\n", GetLastError());
/* using the format feature */ /* using the format feature */
r = doit(FORMAT_MESSAGE_FROM_STRING, "%1!s!", 0, r = doit(FORMAT_MESSAGE_FROM_STRING, "%1!s!", 0,
0, out, sizeof(out)/sizeof(CHAR), "test"); 0, out, sizeof(out)/sizeof(CHAR), "test");
@ -1340,6 +1390,20 @@ static void test_message_from_hmodule(void)
MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL), out, sizeof(out)/sizeof(CHAR), NULL); MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL), out, sizeof(out)/sizeof(CHAR), NULL);
ok(ret != 0, "FormatMessageA returned 0\n"); ok(ret != 0, "FormatMessageA returned 0\n");
/* Test a message string with an insertion without passing any variadic arguments. */
ret = FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_FROM_HMODULE, h, 193 /* ERROR_BAD_EXE_FORMAT */,
MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL), out, sizeof(out)/sizeof(CHAR), NULL);
ok(ret == 0 ||
broken(ret != 0), /* Win9x */
"FormatMessageA returned non-zero\n");
ret = FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_FROM_HMODULE |
FORMAT_MESSAGE_ARGUMENT_ARRAY, h, 193 /* ERROR_BAD_EXE_FORMAT */,
MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL), out, sizeof(out)/sizeof(CHAR), NULL);
ok(ret == 0 ||
broken(ret != 0), /* Win9x */
"FormatMessageA returned non-zero\n");
/*Test nonexistent messageID with varying language ID's Note: FormatMessageW behaves the same*/ /*Test nonexistent messageID with varying language ID's Note: FormatMessageW behaves the same*/
SetLastError(0xdeadbeef); SetLastError(0xdeadbeef);
ret = FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_FROM_HMODULE, h, 3044, ret = FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_FROM_HMODULE, h, 3044,