Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-winehq
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
wine
wine-winehq
Commits
2193b9e8
Commit
2193b9e8
authored
Apr 28, 2010
by
Andrew Nguyen
Committed by
Alexandre Julliard
Apr 28, 2010
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
kernel32: Correct output buffer behavior with empty input strings for FormatMessageA/W.
parent
f50198f6
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
101 additions
and
18 deletions
+101
-18
format_msg.c
dlls/kernel32/format_msg.c
+32
-16
format_msg.c
dlls/kernel32/tests/format_msg.c
+69
-2
No files found.
dlls/kernel32/format_msg.c
View file @
2193b9e8
...
...
@@ -446,22 +446,30 @@ DWORD WINAPI FormatMessageA(
goto
failure
;
TRACE
(
"-- %s
\n
"
,
debugstr_w
(
target
));
destlength
=
WideCharToMultiByte
(
CP_ACP
,
0
,
target
,
-
1
,
NULL
,
0
,
NULL
,
NULL
);
if
(
dwFlags
&
FORMAT_MESSAGE_ALLOCATE_BUFFER
)
{
LPSTR
buf
=
LocalAlloc
(
LMEM_ZEROINIT
,
max
(
nSize
,
destlength
));
WideCharToMultiByte
(
CP_ACP
,
0
,
target
,
-
1
,
buf
,
destlength
,
NULL
,
NULL
);
*
((
LPSTR
*
)
lpBuffer
)
=
buf
;
}
else
{
if
(
nSize
<
destlength
)
/* Only try writing to an output buffer if there are processed characters
* in the temporary output buffer. */
if
(
*
target
)
{
destlength
=
WideCharToMultiByte
(
CP_ACP
,
0
,
target
,
-
1
,
NULL
,
0
,
NULL
,
NULL
);
if
(
dwFlags
&
FORMAT_MESSAGE_ALLOCATE_BUFFER
)
{
SetLastError
(
ERROR_INSUFFICIENT_BUFFER
);
goto
failure
;
LPSTR
buf
=
LocalAlloc
(
LMEM_ZEROINIT
,
max
(
nSize
,
destlength
));
WideCharToMultiByte
(
CP_ACP
,
0
,
target
,
-
1
,
buf
,
destlength
,
NULL
,
NULL
);
*
((
LPSTR
*
)
lpBuffer
)
=
buf
;
}
WideCharToMultiByte
(
CP_ACP
,
0
,
target
,
-
1
,
lpBuffer
,
destlength
,
NULL
,
NULL
);
else
{
if
(
nSize
<
destlength
)
{
SetLastError
(
ERROR_INSUFFICIENT_BUFFER
);
goto
failure
;
}
WideCharToMultiByte
(
CP_ACP
,
0
,
target
,
-
1
,
lpBuffer
,
destlength
,
NULL
,
NULL
);
}
ret
=
destlength
-
1
;
/* null terminator */
}
ret
=
destlength
-
1
;
/* null terminator */
failure:
HeapFree
(
GetProcessHeap
(),
0
,
target
);
HeapFree
(
GetProcessHeap
(),
0
,
from
);
...
...
@@ -542,10 +550,18 @@ DWORD WINAPI FormatMessageW(
talloced
=
strlenW
(
target
)
+
1
;
TRACE
(
"-- %s
\n
"
,
debugstr_w
(
target
));
if
(
dwFlags
&
FORMAT_MESSAGE_ALLOCATE_BUFFER
)
{
/* nSize is the MINIMUM size */
*
((
LPVOID
*
)
lpBuffer
)
=
LocalAlloc
(
LMEM_ZEROINIT
,
max
(
nSize
,
talloced
)
*
sizeof
(
WCHAR
));
strcpyW
(
*
(
LPWSTR
*
)
lpBuffer
,
target
);
/* Only allocate a buffer if there are processed characters in the
* temporary output buffer. If a caller supplies the buffer, then
* a null terminator will be written to it. */
if
(
dwFlags
&
FORMAT_MESSAGE_ALLOCATE_BUFFER
)
{
if
(
*
target
)
{
/* nSize is the MINIMUM size */
*
((
LPVOID
*
)
lpBuffer
)
=
LocalAlloc
(
LMEM_ZEROINIT
,
max
(
nSize
,
talloced
)
*
sizeof
(
WCHAR
));
strcpyW
(
*
(
LPWSTR
*
)
lpBuffer
,
target
);
}
}
else
{
...
...
dlls/kernel32/tests/format_msg.c
View file @
2193b9e8
...
...
@@ -53,6 +53,7 @@ static DWORD __cdecl doitW(DWORD flags, LPCVOID src, DWORD msg_id, DWORD lang_id
static
void
test_message_from_string_wide
(
void
)
{
static
const
WCHAR
test
[]
=
{
't'
,
'e'
,
's'
,
't'
,
0
};
static
const
WCHAR
empty
[]
=
{
0
};
static
const
WCHAR
te
[]
=
{
't'
,
'e'
,
0
};
static
const
WCHAR
st
[]
=
{
's'
,
't'
,
0
};
static
const
WCHAR
t
[]
=
{
't'
,
0
};
...
...
@@ -144,6 +145,25 @@ static void test_message_from_string_wide(void)
ok
(
!
lstrcmpW
(
test
,
out
),
"failed out=%s
\n
"
,
wine_dbgstr_w
(
out
));
ok
(
r
==
4
,
"failed: r=%d
\n
"
,
r
);
/* null string, crashes on Windows */
if
(
0
)
{
SetLastError
(
0xdeadbeef
);
memcpy
(
out
,
init_buf
,
sizeof
(
init_buf
));
r
=
FormatMessageW
(
FORMAT_MESSAGE_FROM_STRING
,
NULL
,
0
,
0
,
out
,
sizeof
(
out
)
/
sizeof
(
WCHAR
),
NULL
);
}
/* empty string */
SetLastError
(
0xdeadbeef
);
memcpy
(
out
,
init_buf
,
sizeof
(
init_buf
));
r
=
FormatMessageW
(
FORMAT_MESSAGE_FROM_STRING
,
empty
,
0
,
0
,
out
,
sizeof
(
out
)
/
sizeof
(
WCHAR
),
NULL
);
error
=
GetLastError
();
ok
(
!
lstrcmpW
(
empty
,
out
),
"failed out=%s
\n
"
,
wine_dbgstr_w
(
out
));
ok
(
r
==
0
,
"succeeded: r=%d
\n
"
,
r
);
ok
(
error
==
0xdeadbeef
,
"last error %u
\n
"
,
error
);
/* format placeholder with no specifier */
SetLastError
(
0xdeadbeef
);
memcpy
(
out
,
init_buf
,
sizeof
(
init_buf
));
...
...
@@ -420,6 +440,27 @@ static void test_message_from_string(void)
ok
(
!
strcmp
(
"test"
,
out
),
"failed out=[%s]
\n
"
,
out
);
ok
(
r
==
4
,
"failed: r=%d
\n
"
,
r
);
/* null string, crashes on Windows */
if
(
0
)
{
SetLastError
(
0xdeadbeef
);
memcpy
(
out
,
init_buf
,
sizeof
(
init_buf
));
r
=
FormatMessageA
(
FORMAT_MESSAGE_FROM_STRING
,
NULL
,
0
,
0
,
out
,
sizeof
(
out
)
/
sizeof
(
CHAR
),
NULL
);
}
/* empty string */
SetLastError
(
0xdeadbeef
);
memcpy
(
out
,
init_buf
,
sizeof
(
init_buf
));
r
=
FormatMessageA
(
FORMAT_MESSAGE_FROM_STRING
,
""
,
0
,
0
,
out
,
sizeof
(
out
)
/
sizeof
(
CHAR
),
NULL
);
ok
(
!
memcmp
(
out
,
init_buf
,
sizeof
(
init_buf
))
||
broken
(
!
strcmp
(
""
,
out
)),
/* Win9x */
"Expected the buffer to be untouched
\n
"
);
ok
(
r
==
0
,
"succeeded: r=%d
\n
"
,
r
);
ok
(
GetLastError
()
==
0xdeadbeef
,
"last error %u
\n
"
,
GetLastError
());
/* format placeholder with no specifier */
SetLastError
(
0xdeadbeef
);
memcpy
(
out
,
init_buf
,
sizeof
(
init_buf
));
...
...
@@ -898,6 +939,15 @@ static void test_message_allocate_buffer(void)
* in any case be safe for FormatMessageA to allocate in the manner that
* MSDN suggests. */
SetLastError
(
0xdeadbeef
);
buf
=
(
char
*
)
0xdeadbeef
;
ret
=
FormatMessageA
(
FORMAT_MESSAGE_FROM_STRING
|
FORMAT_MESSAGE_ALLOCATE_BUFFER
,
""
,
0
,
0
,
(
char
*
)
&
buf
,
0
,
NULL
);
ok
(
ret
==
0
,
"Expected FormatMessageA to return 0, got %u
\n
"
,
ret
);
ok
(
buf
==
NULL
,
"Expected output buffer pointer to be NULL
\n
"
);
ok
(
GetLastError
()
==
0xdeadbeef
,
"Expected last error to be untouched, got %u
\n
"
,
GetLastError
());
buf
=
(
char
*
)
0xdeadbeef
;
ret
=
FormatMessageA
(
FORMAT_MESSAGE_FROM_STRING
|
FORMAT_MESSAGE_ALLOCATE_BUFFER
,
"test"
,
0
,
0
,
(
char
*
)
&
buf
,
0
,
NULL
);
...
...
@@ -966,6 +1016,7 @@ static void test_message_allocate_buffer(void)
static
void
test_message_allocate_buffer_wide
(
void
)
{
static
const
WCHAR
empty
[]
=
{
0
};
static
const
WCHAR
test
[]
=
{
't'
,
'e'
,
's'
,
't'
,
0
};
DWORD
ret
;
...
...
@@ -979,13 +1030,29 @@ static void test_message_allocate_buffer_wide(void)
return
;
}
/* While MSDN suggests that FormatMessage
A
allocates a buffer whose size is
/* While MSDN suggests that FormatMessage
W
allocates a buffer whose size is
* the larger of the output string and the requested buffer size, the tests
* will not try to determine the actual size of the buffer allocated, as
* the return value of LocalSize cannot be trusted for the purpose, and it should
* in any case be safe for FormatMessage
A
to allocate in the manner that
* in any case be safe for FormatMessage
W
to allocate in the manner that
* MSDN suggests. */
if
(
0
)
/* crashes on Windows */
{
buf
=
(
WCHAR
*
)
0xdeadbeef
;
ret
=
FormatMessageW
(
FORMAT_MESSAGE_FROM_STRING
|
FORMAT_MESSAGE_ALLOCATE_BUFFER
,
NULL
,
0
,
0
,
(
WCHAR
*
)
&
buf
,
0
,
NULL
);
}
SetLastError
(
0xdeadbeef
);
buf
=
(
WCHAR
*
)
0xdeadbeef
;
ret
=
FormatMessageW
(
FORMAT_MESSAGE_FROM_STRING
|
FORMAT_MESSAGE_ALLOCATE_BUFFER
,
empty
,
0
,
0
,
(
WCHAR
*
)
&
buf
,
0
,
NULL
);
ok
(
ret
==
0
,
"Expected FormatMessageW to return 0, got %u
\n
"
,
ret
);
ok
(
buf
==
NULL
,
"Expected output buffer pointer to be NULL
\n
"
);
ok
(
GetLastError
()
==
0xdeadbeef
,
"Expected last error to be untouched, got %u
\n
"
,
GetLastError
());
buf
=
(
WCHAR
*
)
0xdeadbeef
;
ret
=
FormatMessageW
(
FORMAT_MESSAGE_FROM_STRING
|
FORMAT_MESSAGE_ALLOCATE_BUFFER
,
test
,
0
,
0
,
(
WCHAR
*
)
&
buf
,
0
,
NULL
);
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment