imm32: Fix output buffer length handling for no-conversion case of GCS_COMPSTR.

Signed-off-by: Nikolay Sivov <nsivov@codeweavers.com>
Signed-off-by: Aric Stewart <aric@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Nikolay Sivov 2019-03-07 11:23:36 +03:00 committed by Alexandre Julliard
parent c4a4146534
commit fd7cda93a3
2 changed files with 42 additions and 11 deletions

View File

@ -1206,23 +1206,29 @@ BOOL WINAPI ImmGetCompositionFontW(HIMC hIMC, LPLOGFONTW lplf)
/* Helpers for the GetCompositionString functions */
static INT CopyCompStringIMEtoClient(InputContextData *data, LPBYTE source, INT slen, LPBYTE target, INT tlen,
BOOL unicode )
/* Source encoding is defined by context, source length is always given in respective characters. Destination buffer
length is always in bytes. */
static INT CopyCompStringIMEtoClient(const InputContextData *data, const void *src, INT src_len, void *dst,
INT dst_len, BOOL unicode)
{
INT rc;
int char_size = unicode ? sizeof(WCHAR) : sizeof(char);
INT ret;
if (is_himc_ime_unicode(data) && !unicode)
rc = WideCharToMultiByte(CP_ACP, 0, (LPWSTR)source, slen, (LPSTR)target, tlen, NULL, NULL);
else if (!is_himc_ime_unicode(data) && unicode)
rc = MultiByteToWideChar(CP_ACP, 0, (LPSTR)source, slen, (LPWSTR)target, tlen) * sizeof(WCHAR);
if (is_himc_ime_unicode(data) ^ unicode)
{
if (unicode)
ret = MultiByteToWideChar(CP_ACP, 0, src, src_len, dst, dst_len);
else
ret = WideCharToMultiByte(CP_ACP, 0, src, src_len, dst, dst_len, NULL, NULL);
ret *= char_size;
}
else
{
int dlen = (unicode)?sizeof(WCHAR):sizeof(CHAR);
memcpy( target, source, min(slen,tlen)*dlen);
rc = slen*dlen;
ret = min(src_len * char_size, dst_len);
memcpy(dst, src, ret);
}
return rc;
return ret;
}
static INT CopyCompAttrIMEtoClient(InputContextData *data, LPBYTE source, INT slen, LPBYTE ssource, INT sslen,

View File

@ -448,6 +448,31 @@ static void test_ImmGetCompositionString(void)
ok(len*sizeof(WCHAR)==wlen,"GCS_COMPATTR(W) not returning correct count\n");
len = ImmGetCompositionStringA(imc, GCS_COMPATTR, NULL, 0);
ok(len==alen,"GCS_COMPATTR(A) not returning correct count\n");
/* Get strings with exactly matching buffer sizes. */
memset(wstring, 0x1a, sizeof(wstring));
memset(cstring, 0x1a, sizeof(cstring));
len = ImmGetCompositionStringA(imc, GCS_COMPSTR, cstring, alen);
ok(len == alen, "Unexpected length %d.\n", len);
ok(cstring[alen] == 0x1a, "Unexpected buffer contents.\n");
len = ImmGetCompositionStringW(imc, GCS_COMPSTR, wstring, wlen);
ok(len == wlen, "Unexpected length %d.\n", len);
ok(wstring[wlen/sizeof(WCHAR)] == 0x1a1a, "Unexpected buffer contents.\n");
/* Get strings with exactly smaller buffer sizes. */
memset(wstring, 0x1a, sizeof(wstring));
memset(cstring, 0x1a, sizeof(cstring));
/* Returns 0 but still fills buffer. */
len = ImmGetCompositionStringA(imc, GCS_COMPSTR, cstring, alen - 1);
ok(!len, "Unexpected length %d.\n", len);
ok(cstring[0] == 'w', "Unexpected buffer contents %s.\n", cstring);
len = ImmGetCompositionStringW(imc, GCS_COMPSTR, wstring, wlen - 1);
ok(len == wlen - 1, "Unexpected length %d.\n", len);
ok(!memcmp(wstring, string, wlen - 1), "Unexpected buffer contents.\n");
}
else
win_skip("Composition string isn't available\n");