[PATCH 2/3] imm32: Fix output buffer length handling for no-conversion case of GCS_COMPSTR.
Nikolay Sivov
nsivov at codeweavers.com
Thu Mar 7 02:23:36 CST 2019
Signed-off-by: Nikolay Sivov <nsivov at codeweavers.com>
---
dlls/imm32/imm.c | 28 +++++++++++++++++-----------
dlls/imm32/tests/imm32.c | 25 +++++++++++++++++++++++++
2 files changed, 42 insertions(+), 11 deletions(-)
diff --git a/dlls/imm32/imm.c b/dlls/imm32/imm.c
index 96a11abba5..a385d884cb 100644
--- a/dlls/imm32/imm.c
+++ b/dlls/imm32/imm.c
@@ -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,
diff --git a/dlls/imm32/tests/imm32.c b/dlls/imm32/tests/imm32.c
index ee1aeb3965..d15fa9c9ff 100644
--- a/dlls/imm32/tests/imm32.c
+++ b/dlls/imm32/tests/imm32.c
@@ -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");
--
2.20.1
More information about the wine-devel
mailing list