From 6c692dc1af1f3402079db2ced1bc4984dc2084d0 Mon Sep 17 00:00:00 2001 From: Akihiro Sagawa Date: Sun, 9 Feb 2020 20:51:33 +0900 Subject: [PATCH] shlwapi: Fix wnsprintfA/wvnsprintfA %S conversion. Signed-off-by: Akihiro Sagawa Signed-off-by: Alexandre Julliard --- dlls/shlwapi/wsprintf.c | 30 ++++++++++++++++++++++++------ 1 file changed, 24 insertions(+), 6 deletions(-) diff --git a/dlls/shlwapi/wsprintf.c b/dlls/shlwapi/wsprintf.c index 6a36b6a28e3..9d4088cc25e 100644 --- a/dlls/shlwapi/wsprintf.c +++ b/dlls/shlwapi/wsprintf.c @@ -245,7 +245,7 @@ static INT WPRINTF_ParseFormatW( LPCWSTR format, WPRINTF_FORMAT *res ) * WPRINTF_GetLen */ static UINT WPRINTF_GetLen( WPRINTF_FORMAT *format, WPRINTF_DATA *arg, - LPSTR number, UINT maxlen ) + LPSTR number, UINT maxlen, BOOL dst_is_wide ) { UINT len; @@ -264,8 +264,18 @@ static UINT WPRINTF_GetLen( WPRINTF_FORMAT *format, WPRINTF_DATA *arg, return (format->precision = len); case WPR_WSTRING: if (!arg->lpcwstr_view) arg->lpcwstr_view = null_stringW; - for (len = 0; !format->precision || (len < format->precision); len++) - if (!*(arg->lpcwstr_view + len)) break; + if (dst_is_wide) + { + for (len = 0; !format->precision || (len < format->precision); len++) + if (!*(arg->lpcwstr_view + len)) break; + } + else + { + LPCWSTR p = arg->lpcwstr_view; + for (len = 0; (!format->precision || len < format->precision) && *p; p++) + len += WideCharToMultiByte( CP_ACP, 0, p, 1, NULL, 0, NULL, NULL ); + if (format->precision && len > format->precision) len = format->precision; + } if (len > maxlen) len = maxlen; return (format->precision = len); case WPR_SIGNED: @@ -365,7 +375,7 @@ INT WINAPI wvnsprintfA( LPSTR buffer, INT maxlen, LPCSTR spec, __ms_va_list args break; } - len = WPRINTF_GetLen( &format, &argData, number, maxlen - 1 ); + len = WPRINTF_GetLen( &format, &argData, number, maxlen - 1, FALSE ); sign = 0; if (!(format.flags & WPRINTF_LEFTALIGN)) for (i = format.precision; i < format.width; i++, maxlen--) @@ -385,7 +395,15 @@ INT WINAPI wvnsprintfA( LPSTR buffer, INT maxlen, LPCSTR spec, __ms_va_list args case WPR_WSTRING: { LPCWSTR ptr = argData.lpcwstr_view; - for (i = 0; i < len; i++) *p++ = (CHAR)*ptr++; + for (i = 0; i < len; ptr++) + { + CHAR mb[5]; /* 5 is MB_LEN_MAX */ + int ret = WideCharToMultiByte( CP_ACP, 0, ptr, 1, mb, sizeof(mb), NULL, NULL ); + i += ret; + if (i > len) ret = len - (p - buffer); + memcpy( p, mb, ret ); + p += ret; + } } break; case WPR_HEXA: @@ -472,7 +490,7 @@ INT WINAPI wvnsprintfW( LPWSTR buffer, INT maxlen, LPCWSTR spec, __ms_va_list ar break; } - len = WPRINTF_GetLen( &format, &argData, number, maxlen - 1 ); + len = WPRINTF_GetLen( &format, &argData, number, maxlen - 1, TRUE ); sign = 0; if (!(format.flags & WPRINTF_LEFTALIGN)) for (i = format.precision; i < format.width; i++, maxlen--)